6.6.66-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 6.6.66-rc1 review
This is the start of the stable review cycle for the 6.6.66 release. There are 356 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 Sat, 14 Dec 2024 14:41:35 +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.6.66-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.6.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.6.66-rc1
Frank Li <[email protected]>
i3c: master: svc: fix possible assignment of the same address to two devices
Frank Li <[email protected]>
i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
Arnd Bergmann <[email protected]>
serial: amba-pl011: fix build regression
Armin Wolf <[email protected]>
platform/x86: asus-wmi: Fix thermal profile initialization
Takashi Iwai <[email protected]>
ALSA: usb-audio: Update UMP group attributes for GTB blocks, too
Thinh Nguyen <[email protected]>
usb: dwc3: ep0: Don't reset resource alloc flag
Wen Gu <[email protected]>
net/smc: fix incorrect SMC-D link group matching logic
Takashi Iwai <[email protected]>
ALSA: hda: Fix build error without CONFIG_SND_DEBUG
Alex Deucher <[email protected]>
drm/amdgpu: rework resume handling for display (v2)
Amadeusz Sławiński <[email protected]>
ASoC: Intel: avs: Fix return status of avs_pcm_hw_constraints_init()
Heming Zhao <[email protected]>
ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume"
Luca Stefani <[email protected]>
btrfs: add cancellation points to trim loops
Jean-Baptiste Maneyrol <[email protected]>
iio: invensense: fix multiple odr switch when FIFO is off
Mathias Nyman <[email protected]>
xhci: dbc: Fix STALL transfer event handling
Zheng Yejian <[email protected]>
mm/damon/vaddr: fix issue in damon_va_evenly_split_region()
Richard Weinberger <[email protected]>
jffs2: Fix rtime decompressor
Kinsey Moore <[email protected]>
jffs2: Prevent rtime decompress memory corruption
Nikolay Kuratov <[email protected]>
KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from kvm_faultin_pfn()
Hari Bathini <[email protected]>
selftests/ftrace: adjust offset for kprobe syntax error test
Yishai Hadas <[email protected]>
vfio/mlx5: Align the page tracking max message size with the device capability
Linus Torvalds <[email protected]>
Revert "unicode: Don't special case ignorable code points"
Damien Le Moal <[email protected]>
x86: Fix build regression with CONFIG_KEXEC_JUMP enabled
Masami Hiramatsu (Google) <[email protected]>
tracing/eprobe: Fix to release eprobe when failed to add dyn_event
Haoyu Li <[email protected]>
clk: en7523: Initialize num before accessing hws in en7523_register_clocks()
Filipe Manana <[email protected]>
btrfs: fix missing snapshot drew unlock when root is dead during swap activation
Wander Lairson Costa <[email protected]>
sched/deadline: Fix warning in migrate_enable for boosted tasks
Peter Zijlstra <[email protected]>
sched/deadline: Move bandwidth accounting into {en,de}queue_dl_entity
Peter Zijlstra <[email protected]>
sched/deadline: Collect sched_dl_entity initialization
Peter Zijlstra <[email protected]>
sched: Unify more update_curr*()
Peter Zijlstra <[email protected]>
sched: Remove vruntime from trace_sched_stat_runtime()
Peter Zijlstra <[email protected]>
sched: Unify runtime accounting across classes
Kir Kolyshkin <[email protected]>
sched/headers: Move 'struct sched_param' out of uapi, to work around glibc/musl breakage
Ingo Molnar <[email protected]>
sched/fair: Rename check_preempt_curr() to wakeup_preempt()
Ingo Molnar <[email protected]>
sched/fair: Rename check_preempt_wakeup() to check_preempt_wakeup_fair()
K Prateek Nayak <[email protected]>
sched/core: Prevent wakeup of ksoftirqd during idle load balance
K Prateek Nayak <[email protected]>
sched/fair: Check idle_cpu() before need_resched() to detect ilb CPU turning busy
K Prateek Nayak <[email protected]>
sched/core: Remove the unnecessary need_resched() check in nohz_csd_func()
David Hildenbrand <[email protected]>
mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a MM
Hugh Dickins <[email protected]>
mempolicy: fix migrate_pages(2) syscall return nr_failed
Adrian Huang <[email protected]>
sched/numa: fix memory leak due to the overwritten vma->numab_state
Raghavendra K T <[email protected]>
sched/numa: Fix mm numa_scan_seq based unconditional scan
Jens Axboe <[email protected]>
io_uring/tctx: work around xa_store() allocation error issue
Rasmus Villemoes <[email protected]>
setlocalversion: work around "git describe" performance
Paulo Alcantara <[email protected]>
smb: client: don't try following DFS links in cifs_tree_connect()
Inochi Amaoto <[email protected]>
serial: 8250_dw: Add Sophgo SG2044 quirk
Dmitry Torokhov <[email protected]>
rtc: cmos: avoid taking rtc_lock for extended period of time
Parker Newman <[email protected]>
misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
Michael Ellerman <[email protected]>
powerpc/prom_init: Fixup missing powermac #size-cells
Uwe Kleine-König <[email protected]>
ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6 21M1CTO1WW
Xi Ruoyao <[email protected]>
MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a
Xiang Liu <[email protected]>
drm/amdgpu/vcn: reset fw_shared when VCPU buffers corrupted on vcn v4.0.3
Alex Far <[email protected]>
ASoC: amd: yc: fix internal mic on Redmi G 2022
Andy Shevchenko <[email protected]>
iio: light: ltr501: Add LTER0303 to the supported devices
Xu Yang <[email protected]>
usb: chipidea: udc: handle USB Error Interrupt if IOC not set
Konstantin Komarov <[email protected]>
fs/ntfs3: Fix case when unmarked clusters intersect with zone
Huacai Chen <[email protected]>
LoongArch: Fix sleeping in atomic context for PREEMPT_RT
Hans de Goede <[email protected]>
ACPI: x86: Clean up Asus entries in acpi_quirk_skip_dmi_ids[]
Hans de Goede <[email protected]>
ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 8 A1-840
Chao Yu <[email protected]>
f2fs: fix to shrink read extent node in batches
Chao Yu <[email protected]>
f2fs: print message if fscorrupted was found in f2fs_new_node_page()
Defa Li <[email protected]>
i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to avoid deadlock
Mengyuan Lou <[email protected]>
PCI: Add ACS quirk for Wangxun FF5xxx NICs
Keith Busch <[email protected]>
PCI: Add 'reset_subordinate' to reset hierarchy below bridge
Esther Shimanovich <[email protected]>
PCI: Detect and trust built-in Thunderbolt chips
Jian-Hong Pan <[email protected]>
PCI: vmd: Set devices to D0 before enabling PM L1 Substates
Nirmal Patel <[email protected]>
PCI: vmd: Add DID 8086:B06F and 8086:B60B for Intel client SKUs
devi priya <[email protected]>
PCI: qcom: Add support for IPQ9574
Jarkko Nikula <[email protected]>
i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request
Qianqiang Liu <[email protected]>
KMSAN: uninit-value in inode_go_dump (5)
Qi Han <[email protected]>
f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode.
Gabriele Monaco <[email protected]>
verification/dot2: Improve dot parser robustness
Kees Cook <[email protected]>
smb: client: memcpy() with surrounding object base address
Yi Yang <[email protected]>
nvdimm: rectify the illogical code within nd_dax_probe()
Barnabás Czémán <[email protected]>
thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens
Barnabás Czémán <[email protected]>
pinctrl: qcom: spmi-mpp: Add PM8937 compatible
Barnabás Czémán <[email protected]>
pinctrl: qcom-pmic-gpio: add support for PM8937
Kai Mäkisara <[email protected]>
scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset
Kai Mäkisara <[email protected]>
scsi: st: Don't modify unknown block number in MTIOCGET
Mukesh Ojha <[email protected]>
leds: class: Protect brightness_show() with led_cdev->led_access mutex
Dmitry Baryshkov <[email protected]>
clk: qcom: tcsrcc-sm8550: add SAR2130P support
Dmitry Baryshkov <[email protected]>
clk: qcom: rpmh: add support for SAR2130P
Dmitry Baryshkov <[email protected]>
clk: qcom: rcg2: add clk_rcg2_shared_floor_ops
Justin Tee <[email protected]>
scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths
Andrii Nakryiko <[email protected]>
bpf: put bpf_link's program when link is safe to be deallocated
Bart Van Assche <[email protected]>
scsi: ufs: core: Make DMA mask configuration more flexible
Mukesh Ojha <[email protected]>
pinmux: Use sequential access to access desc->pinmux data
Yihang Li <[email protected]>
scsi: hisi_sas: Add cond_resched() for no forced preemption model
Tomas Glozar <[email protected]>
rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
Jan Stancek <[email protected]>
tools/rtla: fix collision with glibc sched_attr/sched_set_attr
Uros Bizjak <[email protected]>
tracing: Use atomic64_inc_return() in trace_clock_counter()
Mathieu Desnoyers <[email protected]>
tracing/ftrace: disable preemption in syscall probe
Esben Haabendal <[email protected]>
pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU
Breno Leitao <[email protected]>
netpoll: Use rcu_access_pointer() in __netpoll_setup
Jakub Kicinski <[email protected]>
net/neighbor: clear error in case strict check is not set
Dmitry Antipov <[email protected]>
rocker: fix link status detection in rocker_carrier_init()
Jonas Karlman <[email protected]>
ASoC: hdmi-codec: reorder channel allocation list
Danil Pylaev <[email protected]>
Bluetooth: Set quirks for ATS2851
Danil Pylaev <[email protected]>
Bluetooth: Support new quirks for ATS2851
Danil Pylaev <[email protected]>
Bluetooth: Add new quirks for ATS2851
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
Hilda Wu <[email protected]>
Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables
Andrew Lunn <[email protected]>
dsa: qca8k: Use nested lock to avoid splat
Hou Tao <[email protected]>
bpf: Call free_htab_elem() after htab_unlock_bucket()
Norbert van Bolhuis <[email protected]>
wifi: brcmfmac: Fix oops due to NULL pointer dereference in brcmf_sdiod_sglist_rw()
Jiapeng Chong <[email protected]>
wifi: ipw2x00: libipw_rx_any(): fix bad alignment
Prike Liang <[email protected]>
drm/amdgpu: set the right AMDGPU sg segment limitation
Takashi Iwai <[email protected]>
ALSA: usb-audio: Make mic volume workarounds globally applicable
Xuan Zhuo <[email protected]>
virtio-net: fix overflow inside virtnet_rq_alloc
Victor Zhao <[email protected]>
drm/amdgpu: skip amdgpu_device_cache_pci_state under sriov
Aleksandr Mishin <[email protected]>
fsl/fman: Validate cell-index value obtained from Device Tree
Nihar Chaithanya <[email protected]>
jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree
Ghanshyam Agrawal <[email protected]>
jfs: fix array-index-out-of-bounds in jfs_readdir
Ghanshyam Agrawal <[email protected]>
jfs: fix shift-out-of-bounds in dbSplit
Ghanshyam Agrawal <[email protected]>
jfs: array-index-out-of-bounds fix in dtReadFirst
Levi Yun <[email protected]>
dma-debug: fix a possible deadlock on radix_lock
Lang Yu <[email protected]>
drm/amdgpu: refine error handling in amdgpu_ttm_tt_pin_userptr
Donald Hunter <[email protected]>
netlink: specs: Add missing bitset attrs to ethtool spec
Prike Liang <[email protected]>
drm/amdgpu: Dereference the ATCS ACPI buffer
Victor Lu <[email protected]>
drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for vega20_ih
Philipp Stanner <[email protected]>
drm/sched: memset() 'job' in drm_sched_job_init()
Abhishek Chauhan <[email protected]>
net: stmmac: Programming sequence for VLAN packets with split header
Shengyu Qu <[email protected]>
net: sfp: change quirks for Alcatel Lucent G-010S-P
Manikandan Muralidharan <[email protected]>
drm/panel: simple: Add Microchip AC69T88A LVDS Display panel
Amir Goldstein <[email protected]>
fanotify: allow reporting errors on failure to open fd
Rosen Penev <[email protected]>
wifi: ath5k: add PCI ID for Arcadyan devices
Rosen Penev <[email protected]>
wifi: ath5k: add PCI ID for SX76X
Ignat Korchagin <[email protected]>
net: inet6: do not leave a dangling sk pointer in inet6_create()
Ignat Korchagin <[email protected]>
net: inet: do not leave a dangling sk pointer in inet_create()
Ignat Korchagin <[email protected]>
net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
Ignat Korchagin <[email protected]>
net: af_can: do not leave a dangling sk pointer in can_create()
Ignat Korchagin <[email protected]>
Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc()
Ignat Korchagin <[email protected]>
Bluetooth: L2CAP: do not leave dangling sk pointer on error in l2cap_sock_create()
Ignat Korchagin <[email protected]>
af_packet: avoid erroring out after sock_init_data() in packet_create()
Elena Salomatkina <[email protected]>
net/sched: cbs: Fix integer overflow in cbs_set_port_rate()
Simon Horman <[email protected]>
net: ethernet: fs_enet: Use %pa to format resource_size_t
Simon Horman <[email protected]>
net: fec_mpc52xx_phy: Use %pa to format resource_size_t
Zhu Jun <[email protected]>
samples/bpf: Fix a resource leak
Heiner Kallweit <[email protected]>
r8169: don't apply UDP padding quirk on RTL8126A
Takashi Iwai <[email protected]>
ALSA: hda/conexant: Use the new codec SSID matching
Takashi Iwai <[email protected]>
ALSA: hda: Use own quirk lookup helper
Brahmajit Das <[email protected]>
drm/display: Fix building with GCC 15
Alexander Aring <[email protected]>
dlm: fix possible lkb_resource null dereference
Igor Artemiev <[email protected]>
drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check()
Ping-Ke Shih <[email protected]>
wifi: rtw89: check return value of ieee80211_probereq_get() for RNR
Liao Chen <[email protected]>
drm/mcde: Enable module autoloading
Liao Chen <[email protected]>
drm/bridge: it6505: Enable module autoloading
Joaquín Ignacio Aramendía <[email protected]>
drm: panel-orientation-quirks: Add quirk for AYA NEO GEEK
Joaquín Ignacio Aramendía <[email protected]>
drm: panel-orientation-quirks: Add quirk for AYA NEO Founder edition
Joaquín Ignacio Aramendía <[email protected]>
drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model
Dave Stevenson <[email protected]>
drm/vc4: hvs: Set AXI panic modes for the HVS
Dom Cobley <[email protected]>
drm/vc4: hdmi: Avoid log spam for audio start failure
Callahan Kovacs <[email protected]>
HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support
Reinette Chatre <[email protected]>
selftests/resctrl: Protect against array overflow when reading strings
Cristian Ciocaltea <[email protected]>
regmap: maple: Provide lockdep (sub)class for maple tree's internal lock
Marek Vasut <[email protected]>
soc: imx8m: Probe the SoC driver as platform driver
Peng Fan <[email protected]>
mmc: sdhci-esdhc-imx: enable quirks SDHCI_QUIRK_NO_LED
Keita Aihara <[email protected]>
mmc: core: Add SD card quirk for broken poweroff notification
Rohan Barar <[email protected]>
media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108
David Given <[email protected]>
media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera
Dmitry Perchanov <[email protected]>
media: uvcvideo: RealSense D421 Depth module metadata
Benjamin Tissoires <[email protected]>
HID: add per device quirk to force bind to hid-generic
Stefan Wahren <[email protected]>
spi: spi-fsl-lpspi: Adjust type of scldiv
Breno Leitao <[email protected]>
perf/x86/amd: Warn only on new bits set
Hans de Goede <[email protected]>
ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID
Sarah Maedel <[email protected]>
hwmon: (nct6775) Add 665-ACE/600M-CL to ASUS WMI monitoring list
Marco Elver <[email protected]>
kcsan: Turn report_filterlist_lock into a raw_spinlock
Mark Brown <[email protected]>
kselftest/arm64: Don't leak pipe fds in pac.exec_sign_all()
Boris Burkov <[email protected]>
btrfs: do not clear read-only when adding sprout device
Qu Wenruo <[email protected]>
btrfs: avoid unnecessary device path update for the same device
Johannes Thumshirn <[email protected]>
btrfs: don't take dev_replace rwsem on task already holding it
Thomas Richter <[email protected]>
s390/cpum_sf: Handle CPU hotplug remove during sampling
Mark Brown <[email protected]>
kselftest/arm64: Log fp-stress child startup errors to stdout
Christian Brauner <[email protected]>
epoll: annotate racy check
David Woodhouse <[email protected]>
x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables
Jared Kangas <[email protected]>
kasan: make report_lock a raw spinlock
Kees Cook <[email protected]>
lib: stackinit: hide never-taken branch from compiler
Wengang Wang <[email protected]>
ocfs2: update seq_file index in ocfs2_dlm_seq_next
Ulf Hansson <[email protected]>
mmc: core: Further prevent card detect during shutdown
Hans de Goede <[email protected]>
mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10 tablet
Cosmin Tanislav <[email protected]>
regmap: detach regmap from dev on regmap_exit
Maciej Fijalkowski <[email protected]>
xsk: fix OOB map writes when deleting elements
Tvrtko Ursulin <[email protected]>
dma-fence: Use kernel's sort for merging fences
Tvrtko Ursulin <[email protected]>
dma-fence: Fix reference leak on fence merge failure path
Christian König <[email protected]>
dma-buf: fix dma_fence_array_signaled v4
Maciej Fijalkowski <[email protected]>
bpf: fix OOB devmap writes when deleting elements
David Woodhouse <[email protected]>
x86/kexec: Restore GDT on return from ::preserve_context kexec
Thomas Gleixner <[email protected]>
modpost: Add .irqentry.text to OTHER_SECTIONS
Alex Deucher <[email protected]>
drm/amdgpu/hdp5.2: do a posting read when flushing HDP
Imre Deak <[email protected]>
drm/dp_mst: Fix resetting msg rx state after topology removal
Imre Deak <[email protected]>
drm/dp_mst: Verify request type in the corresponding down message reply
Imre Deak <[email protected]>
drm/dp_mst: Fix MST sideband message body length check
Ricardo Neri <[email protected]>
cacheinfo: Allocate memory during CPU hotplug if not done from the primary CPU
Liequan Che <[email protected]>
bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again
Steve French <[email protected]>
smb3.1.1: fix posix mounts to older servers
Ralph Boehme <[email protected]>
fs/smb/client: cifs_prime_dcache() for SMB3 POSIX reparse points
Ralph Boehme <[email protected]>
fs/smb/client: Implement new SMB3 POSIX type
Ralph Boehme <[email protected]>
fs/smb/client: avoid querying SMB2_OP_QUERY_WSL_EA for SMB3 POSIX
Ryusuke Konishi <[email protected]>
nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry()
Peter Wang <[email protected]>
scsi: ufs: core: Add missing post notify for power mode change
Gwendal Grignou <[email protected]>
scsi: ufs: core: sysfs: Prevent div by zero
Saurav Kashyap <[email protected]>
scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt
Quinn Tran <[email protected]>
scsi: qla2xxx: Fix use after free on unload
Anil Gurumurthy <[email protected]>
scsi: qla2xxx: Supported speed displayed incorrectly for VPorts
Quinn Tran <[email protected]>
scsi: qla2xxx: Fix NVMe and NPIV connect issue
Quinn Tran <[email protected]>
scsi: qla2xxx: Fix abort in bsg timeout
Sahas Leelodharry <[email protected]>
ALSA: hda/realtek: Add support for Samsung Galaxy Book3 360 (NP730QFG)
Nazar Bilinskyi <[email protected]>
ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8
Marie Ramlow <[email protected]>
ALSA: usb-audio: add mixer mapping for Corsair HS80
Mark Rutland <[email protected]>
arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
Catalin Marinas <[email protected]>
arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit ASIDs
Kuan-Wei Chiu <[email protected]>
tracing: Fix cmp_entries_dup() to respect sort() comparison rules
Marc Kleine-Budde <[email protected]>
can: mcp251xfd: mcp251xfd_get_tef_len(): work around erratum DS80000789E 6.
Marc Kleine-Budde <[email protected]>
can: dev: can_set_termination(): allow sleeping GPIOs
Alexander Sverdlin <[email protected]>
watchdog: rti: of: honor timeout-sec property
Jordy Zomer <[email protected]>
ksmbd: fix Out-of-Bounds Write in ksmbd_vfs_stream_write
Jordy Zomer <[email protected]>
ksmbd: fix Out-of-Bounds Read in ksmbd_vfs_stream_read
Bibo Mao <[email protected]>
LoongArch: Add architecture specific huge_pte_clear()
WangYuli <[email protected]>
HID: wacom: fix when get product name maybe null pointer
Roman Gushchin <[email protected]>
mm: page_alloc: move mlocked flag clearance into free_pages_prepare()
Sean Christopherson <[email protected]>
x86/CPU/AMD: WARN when setting EFER.AUTOIBRS if and only if the WRMSR fails
Hou Tao <[email protected]>
bpf: Fix exact match conditions in trie_get_next_key()
Hou Tao <[email protected]>
bpf: Handle in-place update for full LPM trie correctly
Hou Tao <[email protected]>
bpf: Remove unnecessary kfree(im_node) in lpm_trie_update_elem
Hou Tao <[email protected]>
bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
Jakob Hauser <[email protected]>
iio: magnetometer: yas530: use signed integer type for clamp limits
Randy Dunlap <[email protected]>
scatterlist: fix incorrect func name in kernel-doc
Tetsuo Handa <[email protected]>
ocfs2: free inode when ocfs2_get_init_inode() fails
Maíra Canal <[email protected]>
drm/v3d: Enable Performance Counters before clearing them
Nícolas F. R. A. Prado <[email protected]>
ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
John Garry <[email protected]>
scsi: scsi_debug: Fix hrtimer support for ndelay
Suraj Sonawane <[email protected]>
scsi: sg: Fix slab-use-after-free read in sg_release()
Tao Lyu <[email protected]>
bpf: Fix narrow scalar spill onto 64-bit spilled scalar slots
Dan Carpenter <[email protected]>
ASoC: SOF: ipc3-topology: fix resource leaks in sof_ipc3_widget_setup_comp_dai()
Bard Liao <[email protected]>
ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index
Pei Xiao <[email protected]>
spi: mpc52xx: Add cancel_work_sync before module remove
Björn Töpel <[email protected]>
tools: Override makefile ARCH variable if defined, but empty
Takashi Iwai <[email protected]>
ALSA: usb-audio: Notify xrun for low-latency mode
Takashi Iwai <[email protected]>
ALSA: seq: ump: Fix seq port updates per FB info notify
Takashi Iwai <[email protected]>
ALSA: ump: Update substream name from assigned FB names
Takashi Iwai <[email protected]>
ALSA: seq: ump: Use automatic cleanup of kfree()
Zijian Zhang <[email protected]>
tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg
Pei Xiao <[email protected]>
drm/sti: Add __iomem for mixer_dbg_mxn's parameter
Amir Mohammadi <[email protected]>
bpftool: fix potential NULL pointer dereferencing in prog_dump()
Larysa Zaremba <[email protected]>
xsk: always clear DMA mapping information when unmapping the pool
Michal Luczaj <[email protected]>
bpf, vsock: Invoke proto::close on close()
Michal Luczaj <[email protected]>
bpf, vsock: Fix poll() missing a queue
Ziqi Chen <[email protected]>
scsi: ufs: core: Add ufshcd_send_bsg_uic_cmd() for UFS BSG
Bart Van Assche <[email protected]>
scsi: ufs: core: Always initialize the UIC done completion
Chen-Yu Tsai <[email protected]>
drm/bridge: it6505: Fix inverted reset polarity
Kuro Chung <[email protected]>
drm/bridge: it6505: update usleep_range for RC circuit charge time
Frank Li <[email protected]>
i3c: master: Fix dynamic address leak when 'assigned-address' is present
Frank Li <[email protected]>
i3c: master: Extend address status bit to 4 and add I3C_ADDR_SLOT_EXT_DESIRED
Frank Li <[email protected]>
i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
Frank Li <[email protected]>
i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter
Carlos Song <[email protected]>
i3c: master: svc: use slow speed for first broadcast address
Carlos Song <[email protected]>
i3c: master: support to adjust first broadcast address speed
Frank Li <[email protected]>
i3c: master: fix kernel-doc check warning
Frank Li <[email protected]>
i3c: master: svc: add hot join support
Frank Li <[email protected]>
i3c: master: add enable(disable) hot join in sys entry
Chao Yu <[email protected]>
f2fs: fix to drop all discards after creating snapshot on lvm device
Saravana Kannan <[email protected]>
driver core: fw_devlink: Stop trying to optimize cycle detection logic
Saravana Kannan <[email protected]>
driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
Saravana Kannan <[email protected]>
driver core: fw_devlink: Improve logs for cycle detection
Marcelo Dalmas <[email protected]>
ntp: Remove invalid cast in time offset math
Nathan Chancellor <[email protected]>
powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang
Christophe Leroy <[email protected]>
powerpc/vdso: Refactor CFLAGS for CVDSO build
Pratyush Brahma <[email protected]>
iommu/arm-smmu: Defer probe of clients after smmu device bound
Sergey Senozhatsky <[email protected]>
zram: clear IDLE flag in mark_idle()
Sergey Senozhatsky <[email protected]>
zram: do not mark idle slots that cannot be idle
Sergey Senozhatsky <[email protected]>
zram: split memory-tracking and ac-time tracking
Andy-ld Lu <[email protected]>
mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
Rosen Penev <[email protected]>
mmc: mtk-sd: fix devm_clk_get_optional usage
Andy-ld Lu <[email protected]>
mmc: mtk-sd: Fix error handle of probe function
Rosen Penev <[email protected]>
mmc: mtk-sd: use devm_mmc_alloc_host
Thinh Nguyen <[email protected]>
usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED
Michael Grzeschik <[email protected]>
usb: dwc3: ep0: Don't reset resource alloc flag (including ep0)
Thinh Nguyen <[email protected]>
usb: dwc3: gadget: Rewrite endpoint allocation flow
Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure
Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Introduce qmc_{init,exit}_xcc() and their CPM1 version
Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Introduce qmc_init_resource() and its CPM1 version
Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Re-order probe() operations
Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Fix blank line and spaces
Uwe Kleine-König <[email protected]>
soc/fsl: cpm: qmc: Convert to platform remove callback returning void
Kartik Rajput <[email protected]>
serial: amba-pl011: Fix RX stall when DMA is used
Thomas Gleixner <[email protected]>
serial: amba-pl011: Use port lock wrappers
Charles Han <[email protected]>
gpio: grgpio: Add NULL check in grgpio_probe
Bartosz Golaszewski <[email protected]>
gpio: grgpio: use a helper variable to store the address of ofdev->dev
Kuangyi Chiang <[email protected]>
xhci: Fix control transfer error on Etron xHCI host
Kuangyi Chiang <[email protected]>
xhci: Don't issue Reset Device command to Etron xHCI host
Kuangyi Chiang <[email protected]>
xhci: Combine two if statements for Etron xHCI host
Mathias Nyman <[email protected]>
xhci: remove XHCI_TRUST_TX_LENGTH quirk
Basavaraj Natikar <[email protected]>
xhci: Allow RPM on the USB controller (1022:43f7) by default
Oliver Upton <[email protected]>
KVM: arm64: Don't retire aborted MMIO instruction
Fuad Tabba <[email protected]>
KVM: arm64: Change kvm_handle_mmio_return() return polarity
Eric Dumazet <[email protected]>
net: avoid potential UAF in default_operstate()
Jianbo Liu <[email protected]>
net/mlx5e: Remove workaround to avoid syndrome for internal port
Eric Dumazet <[email protected]>
geneve: do not assume mac header is set in geneve_xmit_skb()
Ido Schimmel <[email protected]>
mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4
Christophe JAILLET <[email protected]>
mlxsw: spectrum_acl_flex_keys: Constify struct mlxsw_afk_element_inst
Amit Cohen <[email protected]>
mlxsw: Mark high entropy key blocks
Amit Cohen <[email protected]>
mlxsw: Edit IPv6 key blocks to use one less block for multicast forwarding
Amit Cohen <[email protected]>
mlxsw: spectrum_acl_flex_keys: Add 'ipv4_5b' flex key
Amit Cohen <[email protected]>
mlxsw: Add 'ipv4_5' flex key
Kory Maincent <[email protected]>
ethtool: Fix wrong mod state in case of verbose and no_mask bitset
Pablo Neira Ayuso <[email protected]>
netfilter: nft_set_hash: skip duplicated elements pending gc run
Phil Sutter <[email protected]>
netfilter: ipset: Hold module reference while requesting a module
Xin Long <[email protected]>
net: sched: fix erspan_opt settings in cls_flower
Pablo Neira Ayuso <[email protected]>
netfilter: nft_inner: incorrect percpu area handling under softirq
Yuan Can <[email protected]>
igb: Fix potential invalid memory access in igb_init_module()
Jacob Keller <[email protected]>
ixgbe: downgrade logging of unsupported VF API version to debug
Jacob Keller <[email protected]>
ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5
Louis Leseur <[email protected]>
net/qed: allow old cards not supporting "num_images" to work
Wen Gu <[email protected]>
net/smc: fix LGR and link use-after-free issue
Wen Gu <[email protected]>
net/smc: initialize close_work early to avoid warning
D. Wythe <[email protected]>
net/smc: refactoring initialization of smc sock
Wen Gu <[email protected]>
net/smc: {at|de}tach sndbuf to peer DMB if supported
Wen Gu <[email protected]>
net/smc: add operations to merge sndbuf with peer DMB
Wen Gu <[email protected]>
net/smc: mark optional smcd_ops and check for support when called
Wen Gu <[email protected]>
net/smc: compatible with 128-bits extended GID of virtual ISM device
Wen Gu <[email protected]>
net/smc: define a reserved CHID range for virtual ISM devices
Wen Gu <[email protected]>
net/smc: unify the structs of accept or confirm message for v1 and v2
Wen Gu <[email protected]>
net/smc: introduce sub-functions for smc_clc_send_confirm_accept()
Wen Gu <[email protected]>
net/smc: rename some 'fce' to 'fce_v2x' for clarity
Kuniyuki Iwashima <[email protected]>
tipc: Fix use-after-free of kernel socket in cleanup_bearer().
Ivan Solodovnikov <[email protected]>
dccp: Fix memory leak in dccp_feat_change_recv
Jiri Wiesner <[email protected]>
net/ipv6: release expired exception dst cached in socket
Eric Dumazet <[email protected]>
ipv6: introduce dst_rt6_info() helper
Vadim Fedorenko <[email protected]>
net-timestamp: make sk_tskey more predictable in error path
Armin Wolf <[email protected]>
platform/x86: asus-wmi: Ignore return value when writing thermal policy
Armin Wolf <[email protected]>
platform/x86: asus-wmi: Fix inconsistent use of thermal policies
Mohamed Ghanmi <[email protected]>
platform/x86: asus-wmi: add support for vivobook fan profiles
Dmitry Antipov <[email protected]>
can: j1939: j1939_session_new(): fix skb reference counting
Eric Dumazet <[email protected]>
net: hsr: avoid potential out-of-bound access in fill_frame_info()
Martin Ottens <[email protected]>
net/sched: tbf: correct backlog statistic for GSO packets
Ajay Kaher <[email protected]>
ptp: Add error handling for adjfine callback in ptp_clock_adjtime
Wei Fang <[email protected]>
net: enetc: Do not configure preemptible TCs if SIs do not support
Maximilian Heyne <[email protected]>
selftests: hid: fix typo and exit code
Pablo Neira Ayuso <[email protected]>
netfilter: nft_socket: remove WARN_ON_ONCE on maximum cgroup level
Dmitry Antipov <[email protected]>
netfilter: x_tables: fix LED ID check in led_tg_check()
Jinghao Jia <[email protected]>
ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
Dario Binacchi <[email protected]>
can: f81604: f81604_handle_can_bus_errors(): fix {rx,tx}_errors statisticsDario Binacchi <[email protected]>
can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
Dario Binacchi <[email protected]>
can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
Dario Binacchi <[email protected]>
can: sja1000: sja1000_err(): fix {rx,tx}_errors statisticsDario Binacchi <[email protected]>
can: hi311x: hi3110_can_ist(): fix {rx,tx}_errors statisticsDario Binacchi <[email protected]>
can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
Dario Binacchi <[email protected]>
can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
Dario Binacchi <[email protected]>
can: hi311x: hi3110_can_ist(): fix potential use-after-free
Dario Binacchi <[email protected]>
can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
Dario Binacchi <[email protected]>
can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails
Alexander Kozhinov <[email protected]>
can: gs_usb: add usb endpoint address detection at driver probe step
Marc Kleine-Budde <[email protected]>
can: gs_usb: add VID/PID for Xylanta SAINT3 product family
Yassine Oudjana <[email protected]>
watchdog: mediatek: Make sure system reset gets asserted in mtk_wdt_restart()
Nick Chan <[email protected]>
watchdog: apple: Actually flush writes after requesting watchdog restart
Harini T <[email protected]>
watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency
Oleksandr Ocheretnyi <[email protected]>
iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
-------------
Diffstat:
Documentation/ABI/testing/sysfs-bus-pci | 11 + Documentation/admin-guide/blockdev/zram.rst | 2 +- Documentation/netlink/specs/ethtool.yaml | 7 +- Makefile | 4 +- arch/arm64/kernel/ptrace.c | 6 +- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/mmio.c | 36 +- arch/arm64/mm/context.c | 4 +- arch/loongarch/include/asm/hugetlb.h | 10 + arch/loongarch/mm/tlb.c | 2 +- arch/mips/boot/dts/loongson/ls7a-pch.dtsi | 73 +- arch/powerpc/kernel/prom_init.c | 29 +- arch/powerpc/kernel/vdso/Makefile | 36 +- arch/s390/kernel/perf_cpum_sf.c | 4 +- arch/x86/events/amd/core.c | 10 +- arch/x86/include/asm/pgtable_types.h | 8 +- arch/x86/kernel/cpu/amd.c | 2 +- arch/x86/kernel/relocate_kernel_64.S | 8 + arch/x86/kvm/mmu/mmu.c | 10 +- arch/x86/kvm/mmu/paging_tmpl.h | 5 +- arch/x86/mm/ident_map.c | 6 +- arch/x86/mm/pti.c | 2 +- arch/x86/pci/acpi.c | 119 + drivers/acpi/x86/utils.c | 83 +- drivers/base/cacheinfo.c | 14 +- drivers/base/core.c | 69 +- drivers/base/regmap/internal.h | 1 + drivers/base/regmap/regcache-maple.c | 3 + drivers/base/regmap/regmap.c | 13 + drivers/block/zram/Kconfig | 11 +- drivers/block/zram/zram_drv.c | 50 +- drivers/block/zram/zram_drv.h | 2 +- drivers/bluetooth/btusb.c | 4 + drivers/clk/clk-en7523.c | 4 +- drivers/clk/qcom/clk-rcg.h | 1 + drivers/clk/qcom/clk-rcg2.c | 48 +- drivers/clk/qcom/clk-rpmh.c | 13 + drivers/clk/qcom/tcsrcc-sm8550.c | 18 +- drivers/dma-buf/dma-fence-array.c | 28 +- drivers/dma-buf/dma-fence-unwrap.c | 126 +- drivers/gpio/gpio-grgpio.c | 26 +- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 48 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 5 +- drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c | 6 +- drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c | 30 +- drivers/gpu/drm/amd/amdgpu/vega20_ih.c | 27 + drivers/gpu/drm/bridge/ite-it6505.c | 11 +- drivers/gpu/drm/display/drm_dp_dual_mode_helper.c | 4 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 55 +- drivers/gpu/drm/drm_panel_orientation_quirks.c | 18 + drivers/gpu/drm/mcde/mcde_drv.c | 1 + drivers/gpu/drm/panel/panel-simple.c | 28 + drivers/gpu/drm/radeon/r600_cs.c | 2 +- drivers/gpu/drm/scheduler/sched_main.c | 8 + drivers/gpu/drm/sti/sti_mixer.c | 2 +- drivers/gpu/drm/v3d/v3d_perfmon.c | 2 +- drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +- drivers/gpu/drm/vc4/vc4_hvs.c | 11 + drivers/hid/hid-core.c | 5 +- drivers/hid/hid-generic.c | 3 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-magicmouse.c | 56 +- drivers/hid/wacom_sys.c | 3 +- drivers/hwmon/nct6775-platform.c | 2 + drivers/i3c/master.c | 193 +- drivers/i3c/master/mipi-i3c-hci/dma.c | 2 +- drivers/i3c/master/svc-i3c-master.c | 140 +- .../iio/common/inv_sensors/inv_sensors_timestamp.c | 4 + drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 2 - drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 2 - drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 1 - drivers/iio/light/ltr501.c | 2 + drivers/iio/magnetometer/yamaha-yas530.c | 13 +- drivers/infiniband/core/addr.c | 6 +- drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 + drivers/leds/led-class.c | 14 +- drivers/md/bcache/super.c | 2 +- drivers/media/usb/cx231xx/cx231xx-cards.c | 2 + drivers/media/usb/uvc/uvc_driver.c | 20 + drivers/misc/eeprom/eeprom_93cx6.c | 10 + drivers/mmc/core/bus.c | 2 + drivers/mmc/core/card.h | 7 + drivers/mmc/core/core.c | 3 + drivers/mmc/core/quirks.h | 9 + drivers/mmc/core/sd.c | 2 +- drivers/mmc/host/mtk-sd.c | 64 +- drivers/mmc/host/sdhci-esdhc-imx.c | 6 + drivers/mmc/host/sdhci-pci-core.c | 72 + drivers/mmc/host/sdhci-pci.h | 1 + drivers/net/can/c_can/c_can_main.c | 26 +- drivers/net/can/dev/dev.c | 2 +- drivers/net/can/ifi_canfd/ifi_canfd.c | 58 +- drivers/net/can/m_can/m_can.c | 33 +- drivers/net/can/sja1000/sja1000.c | 65 +- drivers/net/can/spi/hi311x.c | 48 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c | 29 +- drivers/net/can/sun4i_can.c | 22 +- drivers/net/can/usb/ems_usb.c | 58 +- drivers/net/can/usb/f81604.c | 10 +- drivers/net/can/usb/gs_usb.c | 28 +- drivers/net/dsa/qca/qca8k-8xxx.c | 2 +- drivers/net/ethernet/freescale/enetc/enetc.c | 3 + drivers/net/ethernet/freescale/fec_mpc52xx_phy.c | 2 +- drivers/net/ethernet/freescale/fman/fman.c | 1 - drivers/net/ethernet/freescale/fman/fman.h | 3 + drivers/net/ethernet/freescale/fman/mac.c | 5 + .../net/ethernet/freescale/fs_enet/mii-bitbang.c | 2 +- drivers/net/ethernet/intel/igb/igb_main.c | 4 + drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 2 + drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 2 +- drivers/net/ethernet/intel/ixgbevf/ipsec.c | 1 - .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 13 +- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.c | 12 +- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 17 +- .../ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c | 20 +- .../mellanox/mlxsw/spectrum_acl_flex_keys.c | 96 +- .../net/ethernet/mellanox/mlxsw/spectrum_span.c | 2 +- drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +- drivers/net/ethernet/realtek/r8169_main.c | 14 +- drivers/net/ethernet/rocker/rocker_main.c | 2 +- drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 5 + drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 5 + drivers/net/geneve.c | 2 +- drivers/net/phy/sfp.c | 3 +- drivers/net/virtio_net.c | 12 +- drivers/net/vrf.c | 2 +- drivers/net/vxlan/vxlan_core.c | 2 +- drivers/net/wireless/ath/ath5k/pci.c | 2 + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 8 +- drivers/net/wireless/realtek/rtw89/fw.c | 3 + drivers/nvdimm/dax_devs.c | 4 +- drivers/nvdimm/nd.h | 7 + drivers/pci/controller/dwc/pcie-qcom.c | 1 + drivers/pci/controller/vmd.c | 17 +- drivers/pci/pci-sysfs.c | 26 + drivers/pci/pci.c | 2 +- drivers/pci/pci.h | 1 + drivers/pci/probe.c | 30 +- drivers/pci/quirks.c | 15 +- drivers/pinctrl/core.c | 3 + drivers/pinctrl/core.h | 1 + drivers/pinctrl/freescale/Kconfig | 2 +- drivers/pinctrl/pinmux.c | 173 +- drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 + drivers/pinctrl/qcom/pinctrl-spmi-mpp.c | 1 + drivers/platform/x86/asus-wmi.c | 109 +- drivers/ptp/ptp_clock.c | 3 +- drivers/rtc/rtc-cmos.c | 37 +- drivers/s390/net/ism_drv.c | 19 +- drivers/s390/net/qeth_core.h | 4 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 1 + drivers/scsi/lpfc/lpfc_init.c | 2 + drivers/scsi/lpfc/lpfc_sli.c | 41 +- drivers/scsi/qla2xxx/qla_attr.c | 1 + drivers/scsi/qla2xxx/qla_bsg.c | 124 +- drivers/scsi/qla2xxx/qla_mid.c | 1 + drivers/scsi/qla2xxx/qla_os.c | 15 +- drivers/scsi/scsi_debug.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/scsi/st.c | 31 +- drivers/soc/fsl/qe/qmc.c | 141 +- drivers/soc/imx/soc-imx8m.c | 107 +- drivers/spi/spi-fsl-lpspi.c | 7 +- drivers/spi/spi-mpc52xx.c | 1 + drivers/thermal/qcom/tsens-v1.c | 21 +- drivers/thermal/qcom/tsens.c | 3 + drivers/thermal/qcom/tsens.h | 2 +- drivers/tty/serial/8250/8250_dw.c | 5 +- drivers/tty/serial/amba-pl011.c | 79 +- drivers/ufs/core/ufs-sysfs.c | 6 + drivers/ufs/core/ufs_bsg.c | 2 +- drivers/ufs/core/ufshcd-priv.h | 1 + drivers/ufs/core/ufshcd.c | 58 +- drivers/ufs/host/ufs-renesas.c | 9 +- drivers/usb/chipidea/udc.c | 2 +- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/ep0.c | 7 +- drivers/usb/dwc3/gadget.c | 89 +- drivers/usb/dwc3/gadget.h | 1 + drivers/usb/host/xhci-dbgcap.c | 135 +- drivers/usb/host/xhci-dbgcap.h | 2 +- drivers/usb/host/xhci-pci.c | 21 +- drivers/usb/host/xhci-rcar.c | 6 +- drivers/usb/host/xhci-ring.c | 29 +- drivers/usb/host/xhci.c | 19 + drivers/usb/host/xhci.h | 5 +- drivers/vfio/pci/mlx5/cmd.c | 47 +- drivers/watchdog/apple_wdt.c | 2 +- drivers/watchdog/iTCO_wdt.c | 21 +- drivers/watchdog/mtk_wdt.c | 6 + drivers/watchdog/rti_wdt.c | 3 +- drivers/watchdog/xilinx_wwdt.c | 75 +- fs/btrfs/dev-replace.c | 2 + fs/btrfs/extent-tree.c | 7 +- fs/btrfs/free-space-cache.c | 4 +- fs/btrfs/free-space-cache.h | 7 + fs/btrfs/fs.h | 2 + fs/btrfs/inode.c | 1 + fs/btrfs/volumes.c | 50 +- fs/dlm/lock.c | 10 +- fs/eventpoll.c | 6 +- fs/f2fs/extent_cache.c | 69 +- fs/f2fs/inode.c | 4 +- fs/f2fs/node.c | 7 +- fs/f2fs/segment.c | 9 + fs/f2fs/super.c | 12 + fs/gfs2/super.c | 2 + fs/jffs2/compr_rtime.c | 3 + fs/jfs/jfs_dmap.c | 6 + fs/jfs/jfs_dtree.c | 15 + fs/nilfs2/dir.c | 2 +- fs/notify/fanotify/fanotify_user.c | 85 +- fs/ntfs3/run.c | 40 +- fs/ocfs2/dlmglue.c | 1 + fs/ocfs2/localalloc.c | 19 - fs/ocfs2/namei.c | 4 +- fs/smb/client/cifsproto.h | 1 + fs/smb/client/cifssmb.c | 2 +- fs/smb/client/dfs.c | 188 +- fs/smb/client/inode.c | 94 +- fs/smb/client/readdir.c | 54 +- fs/smb/client/reparse.c | 90 +- fs/smb/client/smb2inode.c | 3 +- fs/smb/server/smb2pdu.c | 6 + fs/unicode/mkutf8data.c | 70 + fs/unicode/utf8data.c_shipped | 6703 ++++++++++---------- include/drm/display/drm_dp_mst_helper.h | 7 + include/linux/eeprom_93cx6.h | 11 + include/linux/eventpoll.h | 2 +- include/linux/fanotify.h | 1 + include/linux/fwnode.h | 2 + include/linux/hid.h | 2 + include/linux/i3c/master.h | 33 +- include/linux/leds.h | 2 +- include/linux/mm_types.h | 3 + include/linux/mmc/card.h | 1 + include/linux/pci.h | 6 + include/linux/platform_data/x86/asus-wmi.h | 1 + include/linux/scatterlist.h | 2 +- include/linux/sched.h | 7 +- include/net/bluetooth/hci.h | 14 + include/net/bluetooth/hci_core.h | 10 +- include/net/ip6_fib.h | 6 +- include/net/ip6_route.h | 11 +- include/net/netfilter/nf_tables_core.h | 1 + include/net/smc.h | 28 +- include/sound/ump.h | 11 + include/trace/events/sched.h | 15 +- include/trace/trace_events.h | 36 +- include/uapi/linux/fanotify.h | 1 + include/uapi/linux/sched/types.h | 4 - include/ufs/ufshcd.h | 19 +- io_uring/tctx.c | 13 +- kernel/bpf/devmap.c | 6 +- kernel/bpf/hashtab.c | 56 +- kernel/bpf/lpm_trie.c | 55 +- kernel/bpf/syscall.c | 22 +- kernel/bpf/verifier.c | 1 + kernel/dma/debug.c | 8 +- kernel/kcsan/debugfs.c | 74 +- kernel/sched/core.c | 23 +- kernel/sched/deadline.c | 180 +- kernel/sched/fair.c | 98 +- kernel/sched/idle.c | 4 +- kernel/sched/rt.c | 21 +- kernel/sched/sched.h | 27 +- kernel/sched/stop_task.c | 17 +- kernel/time/ntp.c | 2 +- kernel/trace/trace_clock.c | 2 +- kernel/trace/trace_eprobe.c | 5 + kernel/trace/trace_syscalls.c | 12 + kernel/trace/tracing_map.c | 6 +- lib/stackinit_kunit.c | 1 + mm/damon/vaddr-test.h | 1 + mm/damon/vaddr.c | 4 +- mm/kasan/report.c | 6 +- mm/mempolicy.c | 346 +- mm/page_alloc.c | 15 + mm/swap.c | 20 - net/bluetooth/6lowpan.c | 2 +- net/bluetooth/hci_core.c | 13 +- net/bluetooth/hci_event.c | 7 + net/bluetooth/hci_sync.c | 9 +- net/bluetooth/l2cap_sock.c | 1 + net/bluetooth/rfcomm/sock.c | 10 +- net/can/af_can.c | 1 + net/can/j1939/transport.c | 2 +- net/core/dst_cache.c | 2 +- net/core/filter.c | 2 +- net/core/link_watch.c | 7 +- net/core/neighbour.c | 1 + net/core/netpoll.c | 2 +- net/dccp/feat.c | 6 +- net/ethtool/bitset.c | 48 +- net/hsr/hsr_forward.c | 2 + net/ieee802154/socket.c | 12 +- net/ipv4/af_inet.c | 22 +- net/ipv4/ip_output.c | 13 +- net/ipv4/ip_tunnel.c | 2 +- net/ipv4/tcp_bpf.c | 11 +- net/ipv6/af_inet6.c | 22 +- net/ipv6/icmp.c | 8 +- net/ipv6/ila/ila_lwt.c | 4 +- net/ipv6/ip6_output.c | 31 +- net/ipv6/ip6mr.c | 2 +- net/ipv6/ndisc.c | 2 +- net/ipv6/ping.c | 2 +- net/ipv6/raw.c | 4 +- net/ipv6/route.c | 34 +- net/ipv6/tcp_ipv6.c | 4 +- net/ipv6/udp.c | 11 +- net/ipv6/xfrm6_policy.c | 2 +- net/l2tp/l2tp_ip6.c | 2 +- net/mpls/mpls_iptunnel.c | 2 +- net/netfilter/ipset/ip_set_core.c | 5 + net/netfilter/ipvs/ip_vs_proto.c | 4 +- net/netfilter/ipvs/ip_vs_xmit.c | 14 +- net/netfilter/nf_flow_table_core.c | 8 +- net/netfilter/nf_flow_table_ip.c | 4 +- net/netfilter/nft_inner.c | 59 +- net/netfilter/nft_rt.c | 2 +- net/netfilter/nft_set_hash.c | 16 + net/netfilter/nft_socket.c | 2 +- net/netfilter/xt_LED.c | 4 +- net/packet/af_packet.c | 12 +- net/sched/cls_flower.c | 5 +- net/sched/sch_cbs.c | 2 +- net/sched/sch_tbf.c | 18 +- net/sctp/ipv6.c | 2 +- net/smc/af_smc.c | 226 +- net/smc/smc.h | 8 +- net/smc/smc_clc.c | 297 +- net/smc/smc_clc.h | 50 +- net/smc/smc_core.c | 98 +- net/smc/smc_core.h | 18 +- net/smc/smc_diag.c | 7 +- net/smc/smc_ism.c | 66 +- net/smc/smc_ism.h | 27 +- net/smc/smc_pnet.c | 4 +- net/tipc/udp_media.c | 2 +- net/vmw_vsock/af_vsock.c | 70 +- net/xdp/xsk_buff_pool.c | 5 +- net/xdp/xskmap.c | 2 +- net/xfrm/xfrm_policy.c | 3 +- samples/bpf/test_cgrp2_sock.c | 4 +- scripts/mod/modpost.c | 2 +- scripts/setlocalversion | 54 +- sound/core/seq/seq_ump_client.c | 110 +- sound/core/ump.c | 75 +- sound/pci/hda/hda_auto_parser.c | 61 +- sound/pci/hda/hda_local.h | 28 +- sound/pci/hda/patch_analog.c | 6 +- sound/pci/hda/patch_cirrus.c | 8 +- sound/pci/hda/patch_conexant.c | 36 +- sound/pci/hda/patch_cs8409-tables.c | 2 +- sound/pci/hda/patch_cs8409.h | 2 +- sound/pci/hda/patch_realtek.c | 22 +- sound/pci/hda/patch_sigmatel.c | 22 +- sound/pci/hda/patch_via.c | 2 +- sound/soc/amd/yc/acp6x-mach.c | 14 + sound/soc/codecs/hdmi-codec.c | 144 +- sound/soc/intel/avs/pcm.c | 2 +- sound/soc/mediatek/mt8188/mt8188-mt6359.c | 4 +- sound/soc/sof/ipc3-topology.c | 31 +- sound/usb/endpoint.c | 14 +- sound/usb/midi2.c | 2 + sound/usb/mixer.c | 58 +- sound/usb/mixer_maps.c | 10 + sound/usb/quirks.c | 31 +- sound/usb/usbaudio.h | 4 + tools/bpf/bpftool/prog.c | 17 +- tools/scripts/Makefile.arch | 4 +- tools/testing/selftests/arm64/fp/fp-stress.c | 15 +- tools/testing/selftests/arm64/pauth/pac.c | 3 + .../ftrace/test.d/kprobe/kprobe_syntax_errors.tc | 2 +- tools/testing/selftests/hid/run-hid-tools-tests.sh | 16 +- tools/testing/selftests/resctrl/resctrl_val.c | 4 +- tools/testing/selftests/resctrl/resctrlfs.c | 2 +- tools/tracing/rtla/src/timerlat_top.c | 8 +- tools/tracing/rtla/src/utils.c | 4 +- tools/tracing/rtla/src/utils.h | 2 + tools/verification/dot2/automata.py | 18 +- 384 files changed, 8910 insertions(+), 6170 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/356 iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksandr Ocheretnyi <[email protected]>
[ Upstream commit daa814d784ac034c62ab3fb0ef83daeafef527e2 ]
Commit da23b6faa8bf ("watchdog: iTCO: Add support for Cannon Lake PCH iTCO") does not mask NMI_NOW bit during TCO1_CNT register's value comparison for update_no_reboot_bit() call causing following failure:
...
iTCO_vendor_support: vendor-support=0
iTCO_wdt iTCO_wdt: unable to reset NO_REBOOT flag, device
disabled by hardware/BIOS
...
and this can lead to unexpected NMIs later during regular crashkernel's workflow because of watchdog probe call failures.
This change masks NMI_NOW bit for TCO1_CNT register values to avoid unexpected NMI_NOW bit inversions.
--- drivers/watchdog/iTCO_wdt.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/watchdog/iTCO_wdt.c +19 -2
@@ -82,6 +82,13 @@#define TCO2_CNT (p) (TCOBASE(p) + 0x0a)/* TCO2 Control Register */ #define TCOv2_TMR (p) (TCOBASE(p) + 0x12)/* TCOv2 Timer Initial Value*/ +/* +* NMI_NOW is bit 8 of TCO1_CNT register +* Read/Write +* This bit is implemented as RW but has no effect on HW. +*/ +#define NMI_NOW BIT(8) +/* internal variables */ struct iTCO_wdt_private {struct watchdog_device wddev;
@@ -219,13 +226,23 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)struct iTCO_wdt_private *p = priv;u16 val, newval; - val =inw (TCO1_CNT (p)); +/* +* writing back 1b1 to NMI_NOW of TCO1_CNT register +* causes NMI_NOW bit inversion what consequently does +* not allow to perform the register's value comparison +* properly. +* +* NMI_NOW bit masking for TCO1_CNT register values +* helps to avoid possible NMI_NOW bit inversions on +* following write operation. +*/ + val =inw (TCO1_CNT (p)) & ~NMI_NOW ;if (set) val |=BIT (0 );else val &= ~BIT (0 );outw (val,TCO1_CNT (p)); - newval =inw (TCO1_CNT (p)); + newval =inw (TCO1_CNT (p)) & ~NMI_NOW ;/* make sure the update is successful */ return val != newval ? -EIO :0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 2/356 watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harini T <[email protected]>
[ Upstream commit 006778844c2c132c28cfa90e3570560351e01b9a ]
In the current implementation, the value of max_hw_heartbeat_ms is set to the timeout period expressed in milliseconds and fails to verify if the close window percentage exceeds the maximum value that the hardware supports.
1. Calculate max_hw_heartbeat_ms based on input clock frequency.
2. Update frequency check to require a minimum frequency of 1Mhz.
3. Limit the close and open window percent to hardware supported value to avoid truncation.
4. If the user input timeout exceeds the maximum timeout supported, use only open window and the framework supports the higher timeouts.
--- drivers/watchdog/xilinx_wwdt.c | 75 ++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 12 deletions(-)
drivers/watchdog/xilinx_wwdt.c +63 -12
@@ -2,7 +2,7 @@/* * Window watchdog device driver for Xilinx Versal WWDT * -* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc. +* Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. */ #include <linux/clk.h>
@@ -36,6 +36,12 @@#define XWWDT_CLOSE_WINDOW_PERCENT 50 +/* Maximum count value of each 32 bit window */ +#define XWWDT_MAX_COUNT_WINDOW GENMASK(31, 0) + +/* Maximum count value of closed and open window combined */ +#define XWWDT_MAX_COUNT_WINDOW_COMBINED GENMASK_ULL(32, 1) +static int wwdt_timeout;static int closed_window_percent;
@@ -54,6 +60,8 @@ MODULE_PARM_DESC(closed_window_percent,* @xilinx_wwdt_wdd: watchdog device structure * @freq: source clock frequency of WWDT * @close_percent: Closed window percent +* @closed_timeout: Closed window timeout in ticks +* @open_timeout: Open window timeout in ticks */ struct xwwdt_device {void __iomem *base;
@@ -61,27 +69,22 @@ struct xwwdt_device {struct watchdog_device xilinx_wwdt_wdd;unsigned long freq;u32 close_percent; +u64 closed_timeout; +u64 open_timeout; };static int xilinx_wwdt_start (struct watchdog_device *wdd) {struct xwwdt_device *xdev =watchdog_get_drvdata (wdd);struct watchdog_device *xilinx_wwdt_wdd = &xdev->xilinx_wwdt_wdd; -u64 time_out, closed_timeout, open_timeout;u32 control_status_reg; -/* Calculate timeout count */ - time_out = xdev->freq * wdd->timeout; - closed_timeout =div_u64 (time_out * xdev->close_percent,100 ); - open_timeout = time_out - closed_timeout; - wdd->min_hw_heartbeat_ms = xdev->close_percent *10 * wdd->timeout; -spin_lock (&xdev->spinlock);iowrite32 (XWWDT_MWR_MASK , xdev->base +XWWDT_MWR_OFFSET );iowrite32 (~(u32 )XWWDT_ESR_WEN_MASK , xdev->base +XWWDT_ESR_OFFSET ); -iowrite32 ((u32 )closed_timeout, xdev->base +XWWDT_FWR_OFFSET ); -iowrite32 ((u32 )open_timeout, xdev->base +XWWDT_SWR_OFFSET ); +iowrite32 ((u32 )xdev->closed_timeout, xdev->base +XWWDT_FWR_OFFSET ); +iowrite32 ((u32 )xdev->open_timeout, xdev->base +XWWDT_SWR_OFFSET );/* Enable the window watchdog timer */ control_status_reg =ioread32 (xdev->base +XWWDT_ESR_OFFSET );
@@ -133,7 +136,12 @@ static int xwwdt_probe(struct platform_device *pdev)struct watchdog_device *xilinx_wwdt_wdd;struct device *dev = &pdev->dev;struct xwwdt_device *xdev; +u64 max_per_window_ms; +u64 min_per_window_ms; +u64 timeout_count;struct clk *clk; +u32 timeout_ms; +u64 ms_count;int ret; xdev =devm_kzalloc (dev,sizeof (*xdev),GFP_KERNEL );
@@ -154,12 +162,13 @@ static int xwwdt_probe(struct platform_device *pdev)return PTR_ERR (clk); xdev->freq =clk_get_rate (clk); -if (!xdev->freq) +if (xdev->freq <1000000 )return -EINVAL ; xilinx_wwdt_wdd->min_timeout =XWWDT_MIN_TIMEOUT ; xilinx_wwdt_wdd->timeout =XWWDT_DEFAULT_TIMEOUT ; - xilinx_wwdt_wdd->max_hw_heartbeat_ms =1000 * xilinx_wwdt_wdd->timeout; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = +div64_u64 (XWWDT_MAX_COUNT_WINDOW_COMBINED , xdev->freq) *1000 ;if (closed_window_percent ==0 || closed_window_percent >=100 ) xdev->close_percent =XWWDT_CLOSE_WINDOW_PERCENT ;
@@ -167,6 +176,48 @@ static int xwwdt_probe(struct platform_device *pdev) xdev->close_percent = closed_window_percent;watchdog_init_timeout (xilinx_wwdt_wdd, wwdt_timeout, &pdev->dev); + +/* Calculate ticks for 1 milli-second */ + ms_count =div_u64 (xdev->freq,1000 ); + timeout_ms = xilinx_wwdt_wdd->timeout *1000 ; + timeout_count = timeout_ms * ms_count; + +if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms) { +/* +* To avoid ping restrictions until the minimum hardware heartbeat, +* we will solely rely on the open window and +* adjust the minimum hardware heartbeat to 0. +*/ + xdev->closed_timeout =0 ; + xdev->open_timeout =XWWDT_MAX_COUNT_WINDOW ; + xilinx_wwdt_wdd->min_hw_heartbeat_ms =0 ; + xilinx_wwdt_wdd->max_hw_heartbeat_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms /2 ; + }else { + xdev->closed_timeout =div64_u64 (timeout_count * xdev->close_percent,100 ); + xilinx_wwdt_wdd->min_hw_heartbeat_ms = +div64_u64 (timeout_ms * xdev->close_percent,100 ); + +if (timeout_ms > xilinx_wwdt_wdd->max_hw_heartbeat_ms /2 ) { + max_per_window_ms = xilinx_wwdt_wdd->max_hw_heartbeat_ms /2 ; + min_per_window_ms = timeout_ms - max_per_window_ms; + +if (xilinx_wwdt_wdd->min_hw_heartbeat_ms > max_per_window_ms) { +dev_info (xilinx_wwdt_wdd->parent, +"Closed window cannot be set to %d%%. Using maximum supported value.\n" , + xdev->close_percent); + xdev->closed_timeout = max_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = max_per_window_ms; + }else if (xilinx_wwdt_wdd->min_hw_heartbeat_ms < min_per_window_ms) { +dev_info (xilinx_wwdt_wdd->parent, +"Closed window cannot be set to %d%%. Using minimum supported value.\n" , + xdev->close_percent); + xdev->closed_timeout = min_per_window_ms * ms_count; + xilinx_wwdt_wdd->min_hw_heartbeat_ms = min_per_window_ms; + } + } + xdev->open_timeout = timeout_count - xdev->closed_timeout; + } +spin_lock_init (&xdev->spinlock);watchdog_set_drvdata (xilinx_wwdt_wdd, xdev);watchdog_set_nowayout (xilinx_wwdt_wdd,1 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 3/356 watchdog: apple: Actually flush writes after requesting watchdog restart
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Chan <[email protected]>
[ Upstream commit 51dfe714c03c066aabc815a2bb2adcc998dfcb30 ]
Although there is an existing code comment about flushing the writes, writes were not actually being flushed.
Actually flush the writes by changing readl_relaxed() to readl().
--- drivers/watchdog/apple_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/watchdog/apple_wdt.c +1 -1
@@ -130,7 +130,7 @@ static int apple_wdt_restart(struct watchdog_device *wdd, unsigned long mode,* can take up to ~20-25ms until the SoC is actually reset. Just wait * 50ms here to be safe. */ - (void )readl_relaxed (wdt->regs +APPLE_WDT_WD1_CUR_TIME ); + (void )readl (wdt->regs +APPLE_WDT_WD1_CUR_TIME );mdelay (50 );return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 4/356 watchdog: mediatek: Make sure system reset gets asserted in mtk_wdt_restart()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yassine Oudjana <[email protected]>
[ Upstream commit a1495a21e0b8aad92132dfcf9c6fffc1bde9d5b2 ]
Clear the IRQ enable bit of WDT_MODE before asserting software reset in order to make TOPRGU issue a system reset signal instead of an IRQ.
--- drivers/watchdog/mtk_wdt.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/watchdog/mtk_wdt.c +6 -0
@@ -186,9 +186,15 @@ static int mtk_wdt_restart(struct watchdog_device *wdt_dev, {struct mtk_wdt_dev *mtk_wdt =watchdog_get_drvdata (wdt_dev);void __iomem *wdt_base; +u32 reg; wdt_base = mtk_wdt->wdt_base; +/* Enable reset in order to issue a system reset instead of an IRQ */ + reg =readl (wdt_base +WDT_MODE ); + reg &= ~WDT_MODE_IRQ_EN ; +writel (reg |WDT_MODE_KEY , wdt_base +WDT_MODE ); +while (1 ) {writel (WDT_SWRST_KEY , wdt_base +WDT_SWRST );mdelay (5 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 5/356 can: gs_usb: add VID/PID for Xylanta SAINT3 product family
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
[ Upstream commit 69e2326a21ef409d6c709cb990565331727b9f27 ]
Add support for the Xylanta SAINT3 product family.
Stable-dep-of: 889b2ae9139a ("can: gs_usb: add usb endpoint address detection at driver probe step")
--- drivers/net/can/usb/gs_usb.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/can/usb/gs_usb.c +5 -0
@@ -40,6 +40,9 @@#define USB_ABE_CANDEBUGGER_FD_VENDOR_ID 0x16d0#define USB_ABE_CANDEBUGGER_FD_PRODUCT_ID 0x10b8 +#define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0 +#define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30 +#define GS_USB_ENDPOINT_IN 1#define GS_USB_ENDPOINT_OUT 2
@@ -1530,6 +1533,8 @@ static const struct usb_device_id gs_usb_table[] = { USB_CES_CANEXT_FD_PRODUCT_ID, 0) }, {USB_DEVICE_INTERFACE_NUMBER (USB_ABE_CANDEBUGGER_FD_VENDOR_ID , USB_ABE_CANDEBUGGER_FD_PRODUCT_ID, 0) }, + { USB_DEVICE_INTERFACE_NUMBER(USB_XYLANTA_SAINT3_VENDOR_ID, + USB_XYLANTA_SAINT3_PRODUCT_ID, 0) }, {} /* Terminating entry */ };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 6/356 can: gs_usb: add usb endpoint address detection at driver probe step
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Kozhinov <[email protected]>
[ Upstream commit 889b2ae9139a87b3390f7003cb1bb3d65bf90a26 ]
There is an approach made to implement gs_usb firmware/driver based on Zephyr RTOS. It was found that USB stack of Zephyr RTOS overwrites USB EP addresses, if they have different last 4 bytes in absence of other endpoints.
For example in case of gs_usb candlelight firmware EP-IN is 0x81 and EP-OUT 0x02. If there are no additional USB endpoints, Zephyr RTOS will overwrite EP-OUT to 0x01. More information can be found in the discussion with Zephyr RTOS USB stack maintainer here:
https://github.com/zephyrproject-rtos/zephyr/issues/67812
There are already two different gs_usb FW driver implementations based on Zephyr RTOS:
1. https://github.com/CANnectivity/cannectivity
(by: https://github.com/henrikbrixandersen)
2. https://github.com/zephyrproject-rtos/zephyr/compare/main...KozhinovAlexander:zephyr:gs_usb
(by: https://github.com/KozhinovAlexander)
At the moment both Zephyr RTOS implementations use dummy USB endpoint, to overcome described USB stack behavior from Zephyr itself. Since Zephyr RTOS is intended to be used on microcontrollers with very constrained amount of resources (ROM, RAM) and additional endpoint requires memory, it is more convenient to update the gs_usb driver in the Linux kernel.
To fix this problem, update the gs_usb driver from using hard coded endpoint numbers to evaluate the endpoint descriptors and use the endpoints provided there.
--- drivers/net/can/usb/gs_usb.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/net/can/usb/gs_usb.c +18 -7
@@ -43,9 +43,6 @@#define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0#define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30 -#define GS_USB_ENDPOINT_IN 1 -#define GS_USB_ENDPOINT_OUT 2 -/* Timestamp 32 bit timer runs at 1 MHz (1 µs tick). Worker accounts * for timer overflow (will be after ~71 minutes) */
@@ -336,6 +333,9 @@ struct gs_usb {unsigned int hf_size_rx;u8 active_channels; + +unsigned int pipe_in; +unsigned int pipe_out; };/* 'allocate' a tx context.
@@ -687,7 +687,7 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) resubmit_urb:usb_fill_bulk_urb (urb, parent->udev, -usb_rcvbulkpipe (parent->udev,GS_USB_ENDPOINT_IN ), + parent->pipe_in, hf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent);
@@ -819,7 +819,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, }usb_fill_bulk_urb (urb, dev->udev, -usb_sndbulkpipe (dev->udev,GS_USB_ENDPOINT_OUT ), + dev->parent->pipe_out, hf, dev->hf_size_tx, gs_usb_xmit_callback, txc);
@@ -925,8 +925,7 @@ static int gs_can_open(struct net_device *netdev)/* fill, anchor, and submit rx urb */ usb_fill_bulk_urb (urb, dev->udev, -usb_rcvbulkpipe (dev->udev, -GS_USB_ENDPOINT_IN ), + dev->parent->pipe_in, buf, dev->parent->hf_size_rx, gs_usb_receive_bulk_callback, parent);
@@ -1413,6 +1412,7 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) {struct usb_device *udev =interface_to_usbdev (intf); +struct usb_endpoint_descriptor *ep_in, *ep_out;struct gs_host_frame *hf;struct gs_usb *parent;struct gs_host_config hconf = {
@@ -1422,6 +1422,13 @@ static int gs_usb_probe(struct usb_interface *intf,unsigned int icount, i;int rc; + rc =usb_find_common_endpoints (intf->cur_altsetting, + &ep_in, &ep_out,NULL ,NULL ); +if (rc) { +dev_err (&intf->dev,"Required endpoints not found\n" ); +return rc; + } +/* send host config */ rc = usb_control_msg_send(udev, 0, GS_USB_BREQ_HOST_FORMAT,
@@ -1466,6 +1473,10 @@ static int gs_usb_probe(struct usb_interface *intf,usb_set_intfdata (intf, parent); parent->udev = udev; +/* store the detected endpoints */ + parent->pipe_in =usb_rcvbulkpipe (parent->udev, ep_in->bEndpointAddress); + parent->pipe_out =usb_sndbulkpipe (parent->udev, ep_out->bEndpointAddress); +for (i =0 ; i < icount; i++) {unsigned int hf_size_rx =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 7/356 can: c_can: c_can_handle_bus_err(): update statistics if skb allocation fails
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 9e66242504f49e17481d8e197730faba7d99c934 ]
Ensure that the statistics are always updated, even if the skb allocation fails.
--- drivers/net/can/c_can/c_can_main.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-)
drivers/net/can/c_can/c_can_main.c +17 -9
@@ -1014,49 +1014,57 @@ static int c_can_handle_bus_err(struct net_device *dev,/* propagate the error condition to the CAN stack */ skb =alloc_can_err_skb (dev, &cf); -if (unlikely (!skb)) -return 0 ;/* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (lec_type) {case LEC_STUFF_ERROR :netdev_dbg (dev,"stuff error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; stats->rx_errors++;break ;case LEC_FORM_ERROR :netdev_dbg (dev,"form error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_FORM ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ; stats->rx_errors++;break ;case LEC_ACK_ERROR :netdev_dbg (dev,"ack error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; stats->tx_errors++;break ;case LEC_BIT1_ERROR :netdev_dbg (dev,"bit1 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; stats->tx_errors++;break ;case LEC_BIT0_ERROR :netdev_dbg (dev,"bit0 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; stats->tx_errors++;break ;case LEC_CRC_ERROR :netdev_dbg (dev,"CRC error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; stats->rx_errors++;break ;default :break ; } +if (unlikely (!skb)) +return 0 ; +netif_receive_skb (skb);return 1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 8/356 can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit ee6bf3677ae03569d833795064e17f605c2163c7 ]
Call the function can_change_state() if the allocation of the skb fails, as it handles the cf parameter when it is null.
Additionally, this ensures that the statistics related to state error counters (i. e. warning, passive, and bus-off) are updated.
--- drivers/net/can/sun4i_can.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/can/sun4i_can.c +4 -4
@@ -629,10 +629,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) tx_state = txerr >= rxerr ? state :0 ; rx_state = txerr <= rxerr ? state :0 ; -if (likely (skb)) -can_change_state (dev, cf, tx_state, rx_state); -else - priv->can.state = state; +/* The skb allocation might fail, but can_change_state() +* handles cf == NULL. +*/ +can_change_state (dev, cf, tx_state, rx_state);if (state ==CAN_STATE_BUS_OFF )can_bus_off (dev); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 9/356 can: hi311x: hi3110_can_ist(): fix potential use-after-free
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 9ad86d377ef4a19c75a9c639964879a5b25a433b ]
The commit a22bd630cfff ("can: hi311x: do not report txerr and rxerr during bus-off") removed the reporting of rxerr and txerr even in case of correct operation (i. e. not bus-off).
The error count information added to the CAN frame after netif_rx() is a potential use after free, since there is no guarantee that the skb is in the same state. It might be freed or reused.
Fix the issue by postponing the netif_rx() call in case of txerr and rxerr reporting.
--- drivers/net/can/spi/hi311x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/can/spi/hi311x.c +2 -1
@@ -671,9 +671,9 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) tx_state = txerr >= rxerr ? new_state :0 ; rx_state = txerr <= rxerr ? new_state :0 ;can_change_state (net, cf, tx_state, rx_state); -netif_rx (skb);if (new_state ==CAN_STATE_BUS_OFF ) { +netif_rx (skb);can_bus_off (net);if (priv->can.restart_ms ==0 ) { priv->force_quit =1 ;
@@ -684,6 +684,7 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id) cf->can_id |=CAN_ERR_CNT ; cf->data[6 ] = txerr; cf->data[7 ] = rxerr; +netif_rx (skb); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 10/356 can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 988d4222bf9039a875a3d48f2fe35c317831ff68 ]
The m_can_handle_lec_err() function was incorrectly incrementing only the receive error counter, even in cases of bit or acknowledgment errors that occur during transmission.
Fix the issue by incrementing the appropriate counter based on the type of error.
--- drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
drivers/net/can/m_can/m_can.c +23 -10
@@ -636,47 +636,60 @@ static int m_can_handle_lec_err(struct net_device *dev,u32 timestamp =0 ; cdev->can.can_stats.bus_error++; - stats->rx_errors++;/* propagate the error condition to the CAN stack */ skb =alloc_can_err_skb (dev, &cf); -if (unlikely (!skb)) -return 0 ;/* check for 'last error code' which tells us the * type of the last error to occur on the CAN bus */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (lec_type) {case LEC_STUFF_ERROR :netdev_dbg (dev,"stuff error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ;break ;case LEC_FORM_ERROR :netdev_dbg (dev,"form error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_FORM ; + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ;break ;case LEC_ACK_ERROR :netdev_dbg (dev,"ack error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; + stats->tx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ;break ;case LEC_BIT1_ERROR :netdev_dbg (dev,"bit1 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ;break ;case LEC_BIT0_ERROR :netdev_dbg (dev,"bit0 error\n" ); - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ;break ;case LEC_CRC_ERROR :netdev_dbg (dev,"CRC error\n" ); - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; + stats->rx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ;break ;default :break ; } +if (unlikely (!skb)) +return 0 ; +if (cdev->is_peripheral) timestamp =m_can_get_timestamp (cdev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 11/356 can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit bb03d568bb21b4afe7935d1943bcf68ddea3ea45 ]
The ifi_canfd_handle_lec_err() function was incorrectly incrementing only the receive error counter, even in cases of bit or acknowledgment errors that occur during transmission.
Fix the issue by incrementing the appropriate counter based on the type of error.
--- drivers/net/can/ifi_canfd/ifi_canfd.c | 58 ++++++++++++++++++--------- 1 file changed, 40 insertions(+), 18 deletions(-)
drivers/net/can/ifi_canfd/ifi_canfd.c +40 -18
@@ -390,36 +390,55 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)return 0 ; priv->can.can_stats.bus_error++; - stats->rx_errors++;/* Propagate the error condition to the CAN stack. */ skb =alloc_can_err_skb (ndev, &cf); -if (unlikely (!skb)) -return 0 ;/* Read the error counter register and check for new errors. */ - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (likely (skb)) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; -if (errctr &IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_OVERLOAD ; +if (errctr &IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_OVERLOAD ; + } -if (errctr &IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST ) - cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; +if (errctr &IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_ACK ; + } -if (errctr &IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; +if (errctr &IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT0 ; + } -if (errctr &IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; +if (errctr &IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST ) { + stats->tx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_BIT1 ; + } -if (errctr &IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +if (errctr &IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; + } -if (errctr &IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST ) - cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; +if (errctr &IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[3 ] =CAN_ERR_PROT_LOC_CRC_SEQ ; + } -if (errctr &IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST ) - cf->data[2 ] |=CAN_ERR_PROT_FORM ; +if (errctr &IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST ) { + stats->rx_errors++; +if (likely (skb)) + cf->data[2 ] |=CAN_ERR_PROT_FORM ; + }/* Reset the error counter, ack the IRQ and re-enable the counter. */ writel (IFI_CANFD_ERROR_CTR_ER_RESET , priv->base +IFI_CANFD_ERROR_CTR );
@@ -427,6 +446,9 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev) priv->base + IFI_CANFD_INTERRUPT);writel (IFI_CANFD_ERROR_CTR_ER_ENABLE , priv->base +IFI_CANFD_ERROR_CTR ); +if (unlikely (!skb)) +return 0 ; +netif_receive_skb (skb);return 1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 12/356 can: hi311x: hi3110_can_ist(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 3e4645931655776e757f9fb5ae29371cd7cb21a2 ]
The hi3110_can_ist() function was incorrectly incrementing only the receive error counter, even in cases of bit or acknowledgment errors that occur during transmission.
The fix the issue by incrementing the appropriate counter based on the type of error.
--- drivers/net/can/spi/hi311x.c | 47 ++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-)
drivers/net/can/spi/hi311x.c +29 -18
@@ -697,27 +697,38 @@ static irqreturn_t hi3110_can_ist(int irq, void *dev_id)/* Check for protocol errors */ if (eflag &HI3110_ERR_PROTOCOL_MASK ) { skb =alloc_can_err_skb (net, &cf); -if (!skb) -break ; +if (skb) + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; priv->can.can_stats.bus_error++; - priv->net->stats.rx_errors++; -if (eflag &HI3110_ERR_BITERR ) - cf->data[2 ] |=CAN_ERR_PROT_BIT ; -else if (eflag &HI3110_ERR_FRMERR ) - cf->data[2 ] |=CAN_ERR_PROT_FORM ; -else if (eflag &HI3110_ERR_STUFERR ) - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; -else if (eflag &HI3110_ERR_CRCERR ) - cf->data[3 ] |=CAN_ERR_PROT_LOC_CRC_SEQ ; -else if (eflag &HI3110_ERR_ACKERR ) - cf->data[3 ] |=CAN_ERR_PROT_LOC_ACK ; - - cf->data[6 ] =hi3110_read (spi,HI3110_READ_TEC ); - cf->data[7 ] =hi3110_read (spi,HI3110_READ_REC ); +if (eflag &HI3110_ERR_BITERR ) { + priv->net->stats.tx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_BIT ; + }else if (eflag &HI3110_ERR_FRMERR ) { + priv->net->stats.rx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_FORM ; + }else if (eflag &HI3110_ERR_STUFERR ) { + priv->net->stats.rx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; + }else if (eflag &HI3110_ERR_CRCERR ) { + priv->net->stats.rx_errors++; +if (skb) + cf->data[3 ] |=CAN_ERR_PROT_LOC_CRC_SEQ ; + }else if (eflag &HI3110_ERR_ACKERR ) { + priv->net->stats.tx_errors++; +if (skb) + cf->data[3 ] |=CAN_ERR_PROT_LOC_ACK ; + } +netdev_dbg (priv->net,"Bus Error\n" ); -netif_rx (skb); +if (skb) { + cf->data[6 ] =hi3110_read (spi,HI3110_READ_TEC ); + cf->data[7 ] =hi3110_read (spi,HI3110_READ_REC ); +netif_rx (skb); + } } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 13/356 can: sja1000: sja1000_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 2c4ef3af4b028a0eaaf378df511d3b425b1df61f ]
The sja1000_err() function only incremented the receive error counter and never the transmit error counter, even if the ECC_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the ECC_DIR flag.
--- drivers/net/can/sja1000/sja1000.c | 67 ++++++++++++++++++------------- 1 file changed, 39 insertions(+), 28 deletions(-)
drivers/net/can/sja1000/sja1000.c +39 -28
@@ -416,8 +416,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)int ret =0 ; skb =alloc_can_err_skb (dev, &cf); -if (skb ==NULL ) -return -ENOMEM ; txerr = priv->read_reg (priv,SJA1000_TXERR ); rxerr = priv->read_reg (priv,SJA1000_RXERR );
@@ -425,8 +423,11 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)if (isrc &IRQ_DOI ) {/* data overrun interrupt */ netdev_dbg (dev,"data overrun interrupt\n" ); - cf->can_id |=CAN_ERR_CRTL ; - cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; +if (skb) { + cf->can_id |=CAN_ERR_CRTL ; + cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; + } + stats->rx_over_errors++; stats->rx_errors++;sja1000_write_cmdreg (priv,CMD_CDO );/* clear bit */
@@ -452,7 +453,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)else state =CAN_STATE_ERROR_ACTIVE ; } -if (state !=CAN_STATE_BUS_OFF ) { +if (state !=CAN_STATE_BUS_OFF && skb) { cf->can_id |=CAN_ERR_CNT ; cf->data[6 ] = txerr; cf->data[7 ] = rxerr;
@@ -460,33 +461,38 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)if (isrc &IRQ_BEI ) {/* bus error interrupt */ priv->can.can_stats.bus_error++; - stats->rx_errors++; ecc = priv->read_reg (priv,SJA1000_ECC ); +if (skb) { + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; - -/* set error type */ -switch (ecc &ECC_MASK ) { -case ECC_BIT : - cf->data[2 ] |=CAN_ERR_PROT_BIT ; -break ; -case ECC_FORM : - cf->data[2 ] |=CAN_ERR_PROT_FORM ; -break ; -case ECC_STUFF : - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; -break ; -default : -break ; - } +/* set error type */ +switch (ecc &ECC_MASK ) { +case ECC_BIT : + cf->data[2 ] |=CAN_ERR_PROT_BIT ; +break ; +case ECC_FORM : + cf->data[2 ] |=CAN_ERR_PROT_FORM ; +break ; +case ECC_STUFF : + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +break ; +default : +break ; + } -/* set error location */ - cf->data[3 ] = ecc &ECC_SEG ; +/* set error location */ + cf->data[3 ] = ecc &ECC_SEG ; + }/* Error occurred during transmission? */ -if ((ecc &ECC_DIR ) ==0 ) - cf->data[2 ] |=CAN_ERR_PROT_TX ; +if ((ecc &ECC_DIR ) ==0 ) { + stats->tx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_TX ; + }else { + stats->rx_errors++; + } }if (isrc &IRQ_EPI ) {/* error passive interrupt */
@@ -502,8 +508,10 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)netdev_dbg (dev,"arbitration lost interrupt\n" ); alc = priv->read_reg (priv,SJA1000_ALC ); priv->can.can_stats.arbitration_lost++; - cf->can_id |=CAN_ERR_LOSTARB ; - cf->data[0 ] = alc &0x1f ; +if (skb) { + cf->can_id |=CAN_ERR_LOSTARB ; + cf->data[0 ] = alc &0x1f ; + } }if (state != priv->can.state) {
@@ -516,6 +524,9 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)can_bus_off (dev); } +if (!skb) +return -ENOMEM ; +netif_rx (skb);return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 14/356 can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 595a81988a6fe06eb5849e972c8b9cb21c4e0d54 ]
The sun4i_can_err() function only incremented the receive error counter and never the transmit error counter, even if the STA_ERR_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the STA_ERR_DIR flag.
--- drivers/net/can/sun4i_can.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/net/can/sun4i_can.c +9 -5
@@ -579,11 +579,9 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)/* bus error interrupt */ netdev_dbg (dev,"bus error interrupt\n" ); priv->can.can_stats.bus_error++; - stats->rx_errors++; + ecc =readl (priv->base +SUN4I_REG_STA_ADDR );if (likely (skb)) { - ecc =readl (priv->base +SUN4I_REG_STA_ADDR ); - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;switch (ecc &SUN4I_STA_MASK_ERR ) {
@@ -601,9 +599,15 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status) >> 16;break ; } -/* error occurred during transmission? */ -if ((ecc &SUN4I_STA_ERR_DIR ) ==0 ) + } + +/* error occurred during transmission? */ +if ((ecc &SUN4I_STA_ERR_DIR ) ==0 ) { +if (likely (skb)) cf->data[2 ] |=CAN_ERR_PROT_TX ; + stats->tx_errors++; + }else { + stats->rx_errors++; } }if (isrc &SUN4I_INT_ERR_PASSIVE ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 15/356 can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit 72a7e2e74b3075959f05e622bae09b115957dffe ]
The ems_usb_rx_err() function only incremented the receive error counter and never the transmit error counter, even if the ECC_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the ECC_DIR flag.
--- drivers/net/can/usb/ems_usb.c | 58 ++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 25 deletions(-)
drivers/net/can/usb/ems_usb.c +33 -25
@@ -335,15 +335,14 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)struct net_device_stats *stats = &dev->netdev->stats; skb =alloc_can_err_skb (dev->netdev, &cf); -if (skb ==NULL ) -return ;if (msg->type ==CPC_MSG_TYPE_CAN_STATE ) {u8 state = msg->msg.can_state;if (state &SJA1000_SR_BS ) { dev->can.state =CAN_STATE_BUS_OFF ; - cf->can_id |=CAN_ERR_BUSOFF ; +if (skb) + cf->can_id |=CAN_ERR_BUSOFF ; dev->can.can_stats.bus_off++;can_bus_off (dev->netdev);
@@ -361,44 +360,53 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)/* bus error interrupt */ dev->can.can_stats.bus_error++; - stats->rx_errors++; - cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; +if (skb) { + cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ; -switch (ecc &SJA1000_ECC_MASK ) { -case SJA1000_ECC_BIT : - cf->data[2 ] |=CAN_ERR_PROT_BIT ; -break ; -case SJA1000_ECC_FORM : - cf->data[2 ] |=CAN_ERR_PROT_FORM ; -break ; -case SJA1000_ECC_STUFF : - cf->data[2 ] |=CAN_ERR_PROT_STUFF ; -break ; -default : - cf->data[3 ] = ecc &SJA1000_ECC_SEG ; -break ; +switch (ecc &SJA1000_ECC_MASK ) { +case SJA1000_ECC_BIT : + cf->data[2 ] |=CAN_ERR_PROT_BIT ; +break ; +case SJA1000_ECC_FORM : + cf->data[2 ] |=CAN_ERR_PROT_FORM ; +break ; +case SJA1000_ECC_STUFF : + cf->data[2 ] |=CAN_ERR_PROT_STUFF ; +break ; +default : + cf->data[3 ] = ecc &SJA1000_ECC_SEG ; +break ; + } }/* Error occurred during transmission? */ -if ((ecc &SJA1000_ECC_DIR ) ==0 ) - cf->data[2 ] |=CAN_ERR_PROT_TX ; +if ((ecc &SJA1000_ECC_DIR ) ==0 ) { + stats->tx_errors++; +if (skb) + cf->data[2 ] |=CAN_ERR_PROT_TX ; + }else { + stats->rx_errors++; + } -if (dev->can.state ==CAN_STATE_ERROR_WARNING || - dev->can.state ==CAN_STATE_ERROR_PASSIVE ) { +if (skb && (dev->can.state ==CAN_STATE_ERROR_WARNING || + dev->can.state ==CAN_STATE_ERROR_PASSIVE )) { cf->can_id |=CAN_ERR_CRTL ; cf->data[1 ] = (txerr > rxerr) ?CAN_ERR_CRTL_TX_PASSIVE :CAN_ERR_CRTL_RX_PASSIVE ; } }else if (msg->type ==CPC_MSG_TYPE_OVERRUN ) { - cf->can_id |=CAN_ERR_CRTL ; - cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; +if (skb) { + cf->can_id |=CAN_ERR_CRTL ; + cf->data[1 ] =CAN_ERR_CRTL_RX_OVERFLOW ; + } stats->rx_over_errors++; stats->rx_errors++; } -netif_rx (skb); +if (skb) +netif_rx (skb); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 16/356 can: f81604: f81604_handle_can_bus_errors(): fix {rx,tx}_errors statistics
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dario Binacchi <[email protected]>
[ Upstream commit d7b916540c2ba3d2a88c27b2a6287b39d8eac052 ]
The f81604_handle_can_bus_errors() function only incremented the receive error counter and never the transmit error counter, even if the ECC_DIR flag reported that an error had occurred during transmission.
Increment the receive/transmit error counter based on the value of the ECC_DIR flag.
--- drivers/net/can/usb/f81604.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/net/can/usb/f81604.c +7 -3
@@ -526,7 +526,6 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv,netdev_dbg (netdev,"bus error interrupt\n" ); priv->can.can_stats.bus_error++; - stats->rx_errors++;if (skb) { cf->can_id |=CAN_ERR_PROT |CAN_ERR_BUSERROR ;
@@ -548,10 +547,15 @@ static void f81604_handle_can_bus_errors(struct f81604_port_priv *priv,/* set error location */ cf->data[3 ] = data->ecc &F81604_SJA1000_ECC_SEG ; + } -/* Error occurred during transmission? */ -if ((data->ecc &F81604_SJA1000_ECC_DIR ) ==0 ) +/* Error occurred during transmission? */ +if ((data->ecc &F81604_SJA1000_ECC_DIR ) ==0 ) { + stats->tx_errors++; +if (skb) cf->data[2 ] |=CAN_ERR_PROT_TX ; + }else { + stats->rx_errors++; }set_bit (F81604_CLEAR_ECC , &priv->clear_flags);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 17/356 ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinghao Jia <[email protected]>
[ Upstream commit 146b6f1112eb30a19776d6c323c994e9d67790db ]
Under certain kernel configurations when building with Clang/LLVM, the compiler does not generate a return or jump as the terminator instruction for ip_vs_protocol_init(), triggering the following objtool warning during build time:
vmlinux.o: warning: objtool: ip_vs_protocol_init() falls through to next function __initstub__kmod_ip_vs_rr__935_123_ip_vs_rr_init6()
At runtime, this either causes an oops when trying to load the ipvs module or a boot-time panic if ipvs is built-in. This same issue has been reported by the Intel kernel test robot previously.
Digging deeper into both LLVM and the kernel code reveals this to be a undefined behavior problem. ip_vs_protocol_init() uses a on-stack buffer of 64 chars to store the registered protocol names and leaves it uninitialized after definition. The function calls strnlen() when concatenating protocol names into the buffer. With CONFIG_FORTIFY_SOURCE strnlen() performs an extra step to check whether the last byte of the input char buffer is a null character (commit 3009f891bb9f ("fortify:
Allow strlen() and strnlen() to pass compile-time known lengths")). This, together with possibly other configurations, cause the following IR to be generated:
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #5 section ".init.text" align 16 !kcfi_type !29 {
%1 = alloca [64 x i8], align 16
...14: ; preds = %11
%15 = getelementptr inbounds i8, ptr %1, i64 63
%16 = load i8, ptr %15, align 1
%17 = tail call i1 @llvm.is.constant.i8(i8 %16)
%18 = icmp eq i8 %16, 0
%19 = select i1 %17, i1 %18, i1 false
br i1 %19, label %20, label %23 20: ; preds = %14
%21 = call i64 @strlen(ptr noundef nonnull dereferenceable(1) %1) #23
...
23: ; preds = %14, %11, %20
%24 = call i64 @strnlen(ptr noundef nonnull dereferenceable(1) %1, i64 noundef 64) #24
...
}The above code calculates the address of the last char in the buffer (value %15) and then loads from it (value %16). Because the buffer is never initialized, the LLVM GVN pass marks value %16 as undefined:
%13 = getelementptr inbounds i8, ptr %1, i64 63
br i1 undef, label %14, label %17
This gives later passes (SCCP, in particular) more DCE opportunities by propagating the undef value further, and eventually removes everything after the load on the uninitialized stack location:
define hidden i32 @ip_vs_protocol_init() local_unnamed_addr #0 section ".init.text" align 16 !kcfi_type !11 {
%1 = alloca [64 x i8], align 16
...
12: ; preds = %11
%13 = getelementptr inbounds i8, ptr %1, i64 63
unreachable
}In this way, the generated native code will just fall through to the next function, as LLVM does not generate any code for the unreachable IR instruction and leaves the function without a terminator.
Zero the on-stack buffer to avoid this possible UB.
--- net/netfilter/ipvs/ip_vs_proto.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
net/netfilter/ipvs/ip_vs_proto.c +1 -3
@@ -340,7 +340,7 @@ void __net_exit ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs)int __init ip_vs_protocol_init (void ) { -char protocols[64 ]; +char protocols[64 ] = {0 };#define REGISTER_PROTOCOL (p) \ do { \ register_ip_vs_protocol(p); \
@@ -348,8 +348,6 @@ int __init ip_vs_protocol_init(void)strcat (protocols, (p)->name); \ } while (0) - protocols[0 ] ='\0' ; - protocols[2 ] ='\0' ;#ifdef CONFIG_IP_VS_PROTO_TCP REGISTER_PROTOCOL (&ip_vs_protocol_tcp);#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 18/356 netfilter: x_tables: fix LED ID check in led_tg_check()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit 04317f4eb2aad312ad85c1a17ad81fe75f1f9bc7 ]
Syzbot has reported the following BUG detected by KASAN:
BUG: KASAN: slab-out-of-bounds in strlen+0x58/0x70 Read of size 1 at addr ffff8881022da0c8 by task repro/5879 ... Call Trace: <TASK> dump_stack_lvl+0x241/0x360 ? __pfx_dump_stack_lvl+0x10/0x10 ? __pfx__printk+0x10/0x10 ? _printk+0xd5/0x120 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x183/0x530 print_report+0x169/0x550 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x183/0x530 ? __virt_addr_valid+0x45f/0x530 ? __phys_addr+0xba/0x170 ? strlen+0x58/0x70 kasan_report+0x143/0x180 ? strlen+0x58/0x70 strlen+0x58/0x70 kstrdup+0x20/0x80 led_tg_check+0x18b/0x3c0 xt_check_target+0x3bb/0xa40 ? __pfx_xt_check_target+0x10/0x10 ? stack_depot_save_flags+0x6e4/0x830 ? nft_target_init+0x174/0xc30 nft_target_init+0x82d/0xc30 ? __pfx_nft_target_init+0x10/0x10 ? nf_tables_newrule+0x1609/0x2980 ? nf_tables_newrule+0x1609/0x2980 ? rcu_is_watching+0x15/0xb0 ? nf_tables_newrule+0x1609/0x2980 ? nf_tables_newrule+0x1609/0x2980 ? __kmalloc_noprof+0x21a/0x400 nf_tables_newrule+0x1860/0x2980 ? __pfx_nf_tables_newrule+0x10/0x10 ? __nla_parse+0x40/0x60 nfnetlink_rcv+0x14e5/0x2ab0 ? __pfx_validate_chain+0x10/0x10 ? __pfx_nfnetlink_rcv+0x10/0x10 ? __lock_acquire+0x1384/0x2050 ? netlink_deliver_tap+0x2e/0x1b0 ? __pfx_lock_release+0x10/0x10 ? netlink_deliver_tap+0x2e/0x1b0 netlink_unicast+0x7f8/0x990 ? __pfx_netlink_unicast+0x10/0x10 ? __virt_addr_valid+0x183/0x530 ? __check_object_size+0x48e/0x900 netlink_sendmsg+0x8e4/0xcb0 ? __pfx_netlink_sendmsg+0x10/0x10 ? aa_sock_msg_perm+0x91/0x160 ? __pfx_netlink_sendmsg+0x10/0x10 __sock_sendmsg+0x223/0x270 ____sys_sendmsg+0x52a/0x7e0 ? __pfx_____sys_sendmsg+0x10/0x10 __sys_sendmsg+0x292/0x380 ? __pfx___sys_sendmsg+0x10/0x10 ? lockdep_hardirqs_on_prepare+0x43d/0x780 ? __pfx_lockdep_hardirqs_on_prepare+0x10/0x10 ? exc_page_fault+0x590/0x8c0 ? do_syscall_64+0xb6/0x230 do_syscall_64+0xf3/0x230 entry_SYSCALL_64_after_hwframe+0x77/0x7f ... </TASK>
Since an invalid (without '\0' byte at all) byte sequence may be passed from userspace, add an extra check to ensure that such a sequence is rejected as possible ID and so never passed to 'kstrdup()' and further.
--- net/netfilter/xt_LED.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/xt_LED.c +3 -1
@@ -96,7 +96,9 @@ static int led_tg_check(const struct xt_tgchk_param *par)struct xt_led_info_internal *ledinternal;int err; -if (ledinfo->id[0 ] =='\0' ) +/* Bail out if empty string or not a string at all. */ +if (ledinfo->id[0 ] =='\0' || + !memchr (ledinfo->id,'\0' ,sizeof (ledinfo->id)))return -EINVAL ;mutex_lock (&xt_led_mutex);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 19/356 netfilter: nft_socket: remove WARN_ON_ONCE on maximum cgroup level
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit b7529880cb961d515642ce63f9d7570869bbbdc3 ]
cgroup maximum depth is INT_MAX by default, there is a cgroup toggle to restrict this maximum depth to a more reasonable value not to harm performance. Remove unnecessary WARN_ON_ONCE which is reachable from userspace.
--- net/netfilter/nft_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nft_socket.c +1 -1
@@ -68,7 +68,7 @@ static noinline int nft_socket_cgroup_subtree_level(void)cgroup_put (cgrp); -if (WARN_ON_ONCE (level >255 )) +if (level >255 )return -ERANGE ;if (WARN_ON_ONCE (level <0 ))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 20/356 selftests: hid: fix typo and exit code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilian Heyne <[email protected]>
[ Upstream commit e8f34747bddedaf3895e5d5066e0f71713fff811 ]
The correct exit code to mark a test as skipped is 4.
--- .../testing/selftests/hid/run-hid-tools-tests.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
tools/testing/selftests/hid/run-hid-tools-tests.sh +9 -7
@@ -2,24 +2,26 @@ # SPDX-License-Identifier: GPL-2.0 # Runs tests for the HID subsystem +KSELFTEST_SKIP_TEST=4 + if ! command -v python3 > /dev/null 2>&1; then echo "hid-tools: [SKIP] python3 not installed" - exit 77 + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import pytest" > /dev/null 2>&1; then - echo "hid: [SKIP/ pytest module not installed" - exit 77 + echo "hid: [SKIP] pytest module not installed" + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import pytest_tap" > /dev/null 2>&1; then - echo "hid: [SKIP/ pytest_tap module not installed" - exit 77 + echo "hid: [SKIP] pytest_tap module not installed" + exit $KSELFTEST_SKIP_TEST fi if ! python3 -c "import hidtools" > /dev/null 2>&1; then - echo "hid: [SKIP/ hid-tools module not installed" - exit 77 + echo "hid: [SKIP] hid-tools module not installed" + exit $KSELFTEST_SKIP_TEST fi TARGET=${TARGET:=.}
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 21/356 net: enetc: Do not configure preemptible TCs if SIs do not support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Fang <[email protected]>
[ Upstream commit b2420b8c81ec674552d00c55d46245e5c184b260 ]
Both ENETC PF and VF drivers share enetc_setup_tc_mqprio() to configure MQPRIO. And enetc_setup_tc_mqprio() calls enetc_change_preemptible_tcs() to configure preemptible TCs. However, only PF is able to configure preemptible TCs. Because only PF has related registers, while VF does not have these registers. So for VF, its hw->port pointer is NULL. Therefore, VF will access an invalid pointer when accessing a non-existent register, which will cause a crash issue. The simplified log is as follows.
root@ls1028ardb:~# tc qdisc add dev eno0vf0 parent root handle 100: \ mqprio num_tc 4 map 0 0 1 1 2 2 3 3 queues 1@0 1@1 1@2 1@3 hw 1 [ 187.290775] Unable to handle kernel paging request at virtual address 0000000000001f00 [ 187.424831] pc : enetc_mm_commit_preemptible_tcs+0x1c4/0x400 [ 187.430518] lr : enetc_mm_commit_preemptible_tcs+0x30c/0x400 [ 187.511140] Call trace: [ 187.513588] enetc_mm_commit_preemptible_tcs+0x1c4/0x400 [ 187.518918] enetc_setup_tc_mqprio+0x180/0x214 [ 187.523374] enetc_vf_setup_tc+0x1c/0x30 [ 187.527306] mqprio_enable_offload+0x144/0x178 [ 187.531766] mqprio_init+0x3ec/0x668 [ 187.535351] qdisc_create+0x15c/0x488 [ 187.539023] tc_modify_qdisc+0x398/0x73c [ 187.542958] rtnetlink_rcv_msg+0x128/0x378 [ 187.547064] netlink_rcv_skb+0x60/0x130 [ 187.550910] rtnetlink_rcv+0x18/0x24 [ 187.554492] netlink_unicast+0x300/0x36c [ 187.558425] netlink_sendmsg+0x1a8/0x420 [ 187.606759] ---[ end trace 0000000000000000 ]---
In addition, some PFs also do not support configuring preemptible TCs, such as eno1 and eno3 on LS1028A. It won't crash like it does for VFs, but we should prevent these PFs from accessing these unimplemented registers.
--- drivers/net/ethernet/freescale/enetc/enetc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/freescale/enetc/enetc.c +3 -0
@@ -28,6 +28,9 @@ EXPORT_SYMBOL_GPL(enetc_port_mac_wr);static void enetc_change_preemptible_tcs (struct enetc_ndev_priv *priv,u8 preemptible_tcs) { +if (!(priv->si->hw_features &ENETC_SI_F_QBU )) +return ; + priv->preemptible_tcs = preemptible_tcs;enetc_mm_commit_preemptible_tcs (priv); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 22/356 ptp: Add error handling for adjfine callback in ptp_clock_adjtime
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ajay Kaher <[email protected]>
[ Upstream commit 98337d7c87577ded71114f6976edb70a163e27bc ]
ptp_clock_adjtime sets ptp->dialed_frequency even when adjfine callback returns an error. This causes subsequent reads to return an incorrect value.
Fix this by adding error check before ptp->dialed_frequency is set.
--- drivers/ptp/ptp_clock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/ptp/ptp_clock.c +2 -1
@@ -133,7 +133,8 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)if (ppb > ops->max_adj || ppb < -ops->max_adj)return -ERANGE ; err = ops->adjfine (ops, tx->freq); - ptp->dialed_frequency = tx->freq; +if (!err) + ptp->dialed_frequency = tx->freq; }else if (tx->modes &ADJ_OFFSET ) {if (ops->adjphase) {s32 max_phase_adj = ops->getmaxphase (ops);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 23/356 net/sched: tbf: correct backlog statistic for GSO packets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Ottens <[email protected]>
[ Upstream commit 1596a135e3180c92e42dd1fbcad321f4fb3e3b17 ]
When the length of a GSO packet in the tbf qdisc is larger than the burst size configured the packet will be segmented by the tbf_segment function. Whenever this function is used to enqueue SKBs, the backlog statistic of the tbf is not increased correctly. This can lead to underflows of the 'backlog' byte-statistic value when these packets are dequeued from tbf.
Reproduce the bug:
Ensure that the sender machine has GSO enabled. Configured the tbf on the outgoing interface of the machine as follows (burstsize = 1 MTU):
$ tc qdisc add dev <oif> root handle 1: tbf rate 50Mbit burst 1514 latency 50ms
Send bulk TCP traffic out via this interface, e.g., by running an iPerf3 client on this machine. Check the qdisc statistics:
$ tc -s qdisc show dev <oif>
The 'backlog' byte-statistic has incorrect values while traffic is transferred, e.g., high values due to u32 underflows. When the transfer is stopped, the value is != 0, which should never happen.
This patch fixes this bug by updating the statistics correctly, even if single SKBs of a GSO SKB cannot be enqueued.
--- net/sched/sch_tbf.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
net/sched/sch_tbf.c +12 -6
@@ -208,7 +208,7 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch,struct tbf_sched_data *q =qdisc_priv (sch);struct sk_buff *segs, *nskb;netdev_features_t features =netif_skb_features (skb); -unsigned int len =0 , prev_len =qdisc_pkt_len (skb); +unsigned int len =0 , prev_len =qdisc_pkt_len (skb), seg_len;int ret, nb; segs =skb_gso_segment (skb, features & ~NETIF_F_GSO_MASK );
@@ -219,21 +219,27 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch, nb =0 ; skb_list_walk_safe(segs, segs, nskb) {skb_mark_not_on_list (segs); -qdisc_skb_cb (segs)->pkt_len = segs->len; - len += segs->len; + seg_len = segs->len; +qdisc_skb_cb (segs)->pkt_len = seg_len; ret =qdisc_enqueue (segs, q->qdisc, to_free);if (ret !=NET_XMIT_SUCCESS ) {if (net_xmit_drop_count (ret))qdisc_qstats_drop (sch); }else { nb++; + len += seg_len; } } sch->q.qlen += nb; -if (nb >1 ) + sch->qstats.backlog += len; +if (nb >0 ) {qdisc_tree_reduce_backlog (sch,1 - nb, prev_len - len); -consume_skb (skb); -return nb >0 ?NET_XMIT_SUCCESS :NET_XMIT_DROP ; +consume_skb (skb); +return NET_XMIT_SUCCESS ; + } + +kfree_skb (skb); +return NET_XMIT_DROP ; } static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 24/356 net: hsr: avoid potential out-of-bound access in fill_frame_info()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit b9653d19e556c6afd035602927a93d100a0d7644 ]
syzbot is able to feed a packet with 14 bytes, pretending it is a vlan one.
Since fill_frame_info() is relying on skb->mac_len already, extend the check to cover this case.
BUG: KMSAN: uninit-value in fill_frame_info net/hsr/hsr_forward.c:709 [inline] BUG: KMSAN: uninit-value in hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724 fill_frame_info net/hsr/hsr_forward.c:709 [inline] hsr_forward_skb+0x9ee/0x3b10 net/hsr/hsr_forward.c:724 hsr_dev_xmit+0x2f0/0x350 net/hsr/hsr_device.c:235 __netdev_start_xmit include/linux/netdevice.h:5002 [inline] netdev_start_xmit include/linux/netdevice.h:5011 [inline] xmit_one net/core/dev.c:3590 [inline] dev_hard_start_xmit+0x247/0xa20 net/core/dev.c:3606 __dev_queue_xmit+0x366a/0x57d0 net/core/dev.c:4434 dev_queue_xmit include/linux/netdevice.h:3168 [inline] packet_xmit+0x9c/0x6c0 net/packet/af_packet.c:276 packet_snd net/packet/af_packet.c:3146 [inline] packet_sendmsg+0x91ae/0xa6f0 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:726 __sys_sendto+0x594/0x750 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200 x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Uninit was created at:
slab_post_alloc_hook mm/slub.c:4091 [inline] slab_alloc_node mm/slub.c:4134 [inline] kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4186 kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:587 __alloc_skb+0x363/0x7b0 net/core/skbuff.c:678 alloc_skb include/linux/skbuff.h:1323 [inline] alloc_skb_with_frags+0xc8/0xd00 net/core/skbuff.c:6612 sock_alloc_send_pskb+0xa81/0xbf0 net/core/sock.c:2881 packet_alloc_skb net/packet/af_packet.c:2995 [inline] packet_snd net/packet/af_packet.c:3089 [inline] packet_sendmsg+0x74c6/0xa6f0 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg+0x30f/0x380 net/socket.c:726 __sys_sendto+0x594/0x750 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0x125/0x1d0 net/socket.c:2200 x64_sys_call+0x346a/0x3c30 arch/x86/include/generated/asm/syscalls_64.h:45 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- net/hsr/hsr_forward.c | 2 ++ 1 file changed, 2 insertions(+)
net/hsr/hsr_forward.c +2 -0
@@ -588,6 +588,8 @@ static int fill_frame_info(struct hsr_frame_info *frame, frame->is_vlan = true;if (frame->is_vlan) { + if (skb->mac_len < offsetofend(struct hsr_vlan_ethhdr, vlanhdr)) +return -EINVAL ; vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;/* FIXME: */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 25/356 can: j1939: j1939_session_new(): fix skb reference counting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Antipov <[email protected]>
[ Upstream commit a8c695005bfe6569acd73d777ca298ddddd66105 ]
Since j1939_session_skb_queue() does an extra skb_get() for each new skb, do the same for the initial one in j1939_session_new() to avoid refcount underflow.
--- net/can/j1939/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/can/j1939/transport.c +1 -1
@@ -1505,7 +1505,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv, session->state =J1939_SESSION_NEW ;skb_queue_head_init (&session->skb_queue); -skb_queue_tail (&session->skb_queue, skb); +skb_queue_tail (&session->skb_queue,skb_get (skb)); skcb =j1939_skb_to_cb (skb);memcpy (&session->skcb, skcb,sizeof (session->skcb));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 26/356 platform/x86: asus-wmi: add support for vivobook fan profiles
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Ghanmi <[email protected]>
[ Upstream commit bcbfcebda2cbc6a10a347d726e4a4f69e43a864e ]
Add support for vivobook fan profiles wmi call on the ASUS VIVOBOOK to adjust power limits.
These fan profiles have a different device id than the ROG series and different order. This reorders the existing modes.
As part of keeping the patch clean the throttle_thermal_policy_available boolean stored in the driver struct is removed and throttle_thermal_policy_dev is used in place (as on init it is zeroed).
Stable-dep-of: 25fb5f47f34d ("platform/x86: asus-wmi: Ignore return value when writing thermal policy")
--- drivers/platform/x86/asus-wmi.c | 120 ++++++++++++--------- include/linux/platform_data/x86/asus-wmi.h | 1 + 2 files changed, 71 insertions(+), 50 deletions(-)
drivers/platform/x86/asus-wmi.c +70 -50
@@ -95,6 +95,12 @@ module_param(fnlock_default, bool, 0444);#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST 1#define ASUS_THROTTLE_THERMAL_POLICY_SILENT 2 +#define ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO 0 +#define ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO 1 +#define ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO 2 + +#define PLATFORM_PROFILE_MAX 2 +#define USB_INTEL_XUSB2PR 0xD0#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
@@ -269,8 +275,8 @@ struct asus_wmi {bool kbd_rgb_mode_available;bool kbd_rgb_state_available; -bool throttle_thermal_policy_available;u8 throttle_thermal_policy_mode; +u32 throttle_thermal_policy_dev;bool cpu_fan_curve_available;bool gpu_fan_curve_available;
@@ -2912,7 +2918,7 @@ static int fan_curve_get_factory_default(struct asus_wmi *asus, u32 fan_dev)int err, fan_idx;u8 mode =0 ; -if (asus->throttle_thermal_policy_available) +if (asus->throttle_thermal_policy_dev) mode = asus->throttle_thermal_policy_mode;/* DEVID_<C/G>PU_FAN_CURVE is switched for OVERBOOST vs SILENT */ if (mode ==2 )
@@ -3119,7 +3125,7 @@ static ssize_t fan_curve_enable_store(struct device *dev,* For machines with throttle this is the only way to reset fans * to default mode of operation (does not erase curve data). */ -if (asus->throttle_thermal_policy_available) { +if (asus->throttle_thermal_policy_dev) { err =throttle_thermal_policy_write (asus);if (err)return err;
@@ -3336,8 +3342,8 @@ static const struct attribute_group asus_fan_curve_attr_group = {__ATTRIBUTE_GROUPS (asus_fan_curve_attr);/* -* Must be initialised after throttle_thermal_policy_check_present() as -* we check the status of throttle_thermal_policy_available during init. +* Must be initialised after throttle_thermal_policy_dev is set as +* we check the status of throttle_thermal_policy_dev during init. */ static int asus_wmi_custom_fan_curve_init (struct asus_wmi *asus) {
@@ -3378,38 +3384,13 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus) }/* Throttle thermal policy ****************************************************/ - -static int throttle_thermal_policy_check_present (struct asus_wmi *asus) -{ -u32 result; -int err; - - asus->throttle_thermal_policy_available = false; - - err =asus_wmi_get_devstate (asus, -ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY , - &result); -if (err) { -if (err == -ENODEV ) -return 0 ; -return err; - } - -if (result &ASUS_WMI_DSTS_PRESENCE_BIT ) - asus->throttle_thermal_policy_available = true; - -return 0 ; -} -static int throttle_thermal_policy_write (struct asus_wmi *asus) { -int err; -u8 value; +u8 value = asus->throttle_thermal_policy_mode;u32 retval; +int err; - value = asus->throttle_thermal_policy_mode; - - err =asus_wmi_set_devstate (ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY , + err =asus_wmi_set_devstate (asus->throttle_thermal_policy_dev, value, &retval); sysfs_notify(&asus->platform_device->dev.kobj, NULL,
@@ -3439,7 +3420,7 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)static int throttle_thermal_policy_set_default (struct asus_wmi *asus) { -if (!asus->throttle_thermal_policy_available) +if (!asus->throttle_thermal_policy_dev)return 0 ; asus->throttle_thermal_policy_mode =ASUS_THROTTLE_THERMAL_POLICY_DEFAULT ;
@@ -3451,7 +3432,7 @@ static int throttle_thermal_policy_switch_next(struct asus_wmi *asus)u8 new_mode = asus->throttle_thermal_policy_mode +1 ;int err; -if (new_mode >ASUS_THROTTLE_THERMAL_POLICY_SILENT ) +if (new_mode >PLATFORM_PROFILE_MAX ) new_mode =ASUS_THROTTLE_THERMAL_POLICY_DEFAULT ; asus->throttle_thermal_policy_mode = new_mode;
@@ -3490,7 +3471,7 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,if (result <0 )return result; -if (new_mode >ASUS_THROTTLE_THERMAL_POLICY_SILENT ) +if (new_mode >PLATFORM_PROFILE_MAX )return -EINVAL ; asus->throttle_thermal_policy_mode = new_mode;
@@ -3507,10 +3488,52 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,return count; } -// Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent +/* +* Throttle thermal policy: 0 - default, 1 - overboost, 2 - silent +*/ static DEVICE_ATTR_RW (throttle_thermal_policy);/* Platform profile ***********************************************************/ +static int asus_wmi_platform_profile_to_vivo (struct asus_wmi *asus,int mode) +{ +bool vivo; + + vivo = asus->throttle_thermal_policy_dev ==ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ; + +if (vivo) { +switch (mode) { +case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT : +return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO ; +case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST : +return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO ; +case ASUS_THROTTLE_THERMAL_POLICY_SILENT : +return ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO ; + } + } + +return mode; +} + +static int asus_wmi_platform_profile_mode_from_vivo (struct asus_wmi *asus,int mode) +{ +bool vivo; + + vivo = asus->throttle_thermal_policy_dev ==ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ; + +if (vivo) { +switch (mode) { +case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO : +return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT ; +case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO : +return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST ; +case ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO : +return ASUS_THROTTLE_THERMAL_POLICY_SILENT ; + } + } + +return mode; +} +static int asus_wmi_platform_profile_get (struct platform_profile_handler *pprof,enum platform_profile_option *profile) {
@@ -3518,10 +3541,9 @@ static int asus_wmi_platform_profile_get(struct platform_profile_handler *pprof,int tp; asus = container_of(pprof, struct asus_wmi, platform_profile_handler); - tp = asus->throttle_thermal_policy_mode; -switch (tp) { +switch (asus_wmi_platform_profile_mode_from_vivo (asus, tp)) {case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT : *profile =PLATFORM_PROFILE_BALANCED ;break ;
@@ -3560,7 +3582,7 @@ static int asus_wmi_platform_profile_set(struct platform_profile_handler *pprof,return -EOPNOTSUPP ; } - asus->throttle_thermal_policy_mode = tp; + asus->throttle_thermal_policy_mode =asus_wmi_platform_profile_to_vivo (asus, tp);return throttle_thermal_policy_write (asus); }
@@ -3573,7 +3595,7 @@ static int platform_profile_setup(struct asus_wmi *asus)* Not an error if a component platform_profile relies on is unavailable * so early return, skipping the setup of platform_profile. */ -if (!asus->throttle_thermal_policy_available) +if (!asus->throttle_thermal_policy_dev)return 0 ;dev_info (dev,"Using throttle_thermal_policy for platform_profile support\n" );
@@ -3870,7 +3892,7 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)if (code ==NOTIFY_KBD_FBM || code ==NOTIFY_KBD_TTP ) {if (asus->fan_boost_mode_available)fan_boost_mode_switch_next (asus); -if (asus->throttle_thermal_policy_available) +if (asus->throttle_thermal_policy_dev)throttle_thermal_policy_switch_next (asus);return ;
@@ -4075,7 +4097,7 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,else if (attr == &dev_attr_fan_boost_mode.attr) ok = asus->fan_boost_mode_available;else if (attr == &dev_attr_throttle_thermal_policy.attr) - ok = asus->throttle_thermal_policy_available; + ok = asus->throttle_thermal_policy_dev !=0 ;else if (attr == &dev_attr_ppt_pl2_sppt.attr) ok = asus->ppt_pl2_sppt_available;else if (attr == &dev_attr_ppt_pl1_spl.attr)
@@ -4365,16 +4387,15 @@ static int asus_wmi_add(struct platform_device *pdev) asus->panel_overdrive_available =asus_wmi_dev_is_present (asus,ASUS_WMI_DEVID_PANEL_OD ); asus->mini_led_mode_available =asus_wmi_dev_is_present (asus,ASUS_WMI_DEVID_MINI_LED_MODE ); +if (asus_wmi_dev_is_present (asus,ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY )) + asus->throttle_thermal_policy_dev =ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY ; +else if (asus_wmi_dev_is_present (asus,ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO )) + asus->throttle_thermal_policy_dev =ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ; + err =fan_boost_mode_check_present (asus);if (err) goto fail_fan_boost_mode; - err =throttle_thermal_policy_check_present (asus); -if (err) - goto fail_throttle_thermal_policy; -else -throttle_thermal_policy_set_default (asus); - err =platform_profile_setup (asus);if (err) goto fail_platform_profile_setup;
@@ -4461,7 +4482,6 @@ static int asus_wmi_add(struct platform_device *pdev) fail_input:asus_wmi_sysfs_exit (asus->platform_device); fail_sysfs: -fail_throttle_thermal_policy: fail_custom_fan_curve: fail_platform_profile_setup:if (asus->platform_profile_support)
include/linux/platform_data/x86/asus-wmi.h +1 -0
@@ -60,6 +60,7 @@#define ASUS_WMI_DEVID_LIGHTBAR 0x00050025#define ASUS_WMI_DEVID_FAN_BOOST_MODE 0x00110018#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY 0x00120075 +#define ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO 0x00110019/* Misc */ #define ASUS_WMI_DEVID_PANEL_OD 0x00050019
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 27/356 platform/x86: asus-wmi: Fix inconsistent use of thermal policies
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 895085ec3f2ed7a26389943729e2904df1f88dc0 ]
When changing the thermal policy using the platform profile API, a Vivobook thermal policy is stored in throttle_thermal_policy_mode.
However everywhere else a normal thermal policy is stored inside this variable, potentially confusing the platform profile.
Fix this by always storing normal thermal policy values inside throttle_thermal_policy_mode and only do the conversion when writing the thermal policy to hardware. This also fixes the order in which throttle_thermal_policy_switch_next() steps through the thermal modes on Vivobook machines.
Stable-dep-of: 25fb5f47f34d ("platform/x86: asus-wmi: Ignore return value when writing thermal policy")
--- drivers/platform/x86/asus-wmi.c | 64 +++++++++++---------------------- 1 file changed, 21 insertions(+), 43 deletions(-)
drivers/platform/x86/asus-wmi.c +21 -43
@@ -3386,10 +3386,28 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)/* Throttle thermal policy ****************************************************/ static int throttle_thermal_policy_write (struct asus_wmi *asus) { -u8 value = asus->throttle_thermal_policy_mode;u32 retval; +u8 value;int err; +if (asus->throttle_thermal_policy_dev ==ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ) { +switch (asus->throttle_thermal_policy_mode) { +case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT : + value =ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO ; +break ; +case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST : + value =ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO ; +break ; +case ASUS_THROTTLE_THERMAL_POLICY_SILENT : + value =ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO ; +break ; +default : +return -EINVAL ; + } + }else { + value = asus->throttle_thermal_policy_mode; + } + err =asus_wmi_set_devstate (asus->throttle_thermal_policy_dev, value, &retval);
@@ -3494,46 +3512,6 @@ static ssize_t throttle_thermal_policy_store(struct device *dev,static DEVICE_ATTR_RW (throttle_thermal_policy);/* Platform profile ***********************************************************/ -static int asus_wmi_platform_profile_to_vivo (struct asus_wmi *asus,int mode) -{ -bool vivo; - - vivo = asus->throttle_thermal_policy_dev ==ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ; - -if (vivo) { -switch (mode) { -case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT : -return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO ; -case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST : -return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO ; -case ASUS_THROTTLE_THERMAL_POLICY_SILENT : -return ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO ; - } - } - -return mode; -} - -static int asus_wmi_platform_profile_mode_from_vivo (struct asus_wmi *asus,int mode) -{ -bool vivo; - - vivo = asus->throttle_thermal_policy_dev ==ASUS_WMI_DEVID_THROTTLE_THERMAL_POLICY_VIVO ; - -if (vivo) { -switch (mode) { -case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT_VIVO : -return ASUS_THROTTLE_THERMAL_POLICY_DEFAULT ; -case ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST_VIVO : -return ASUS_THROTTLE_THERMAL_POLICY_OVERBOOST ; -case ASUS_THROTTLE_THERMAL_POLICY_SILENT_VIVO : -return ASUS_THROTTLE_THERMAL_POLICY_SILENT ; - } - } - -return mode; -} -static int asus_wmi_platform_profile_get (struct platform_profile_handler *pprof,enum platform_profile_option *profile) {
@@ -3543,7 +3521,7 @@ static int asus_wmi_platform_profile_get(struct platform_profile_handler *pprof, asus = container_of(pprof, struct asus_wmi, platform_profile_handler); tp = asus->throttle_thermal_policy_mode; -switch (asus_wmi_platform_profile_mode_from_vivo (asus, tp)) { +switch (tp) {case ASUS_THROTTLE_THERMAL_POLICY_DEFAULT : *profile =PLATFORM_PROFILE_BALANCED ;break ;
@@ -3582,7 +3560,7 @@ static int asus_wmi_platform_profile_set(struct platform_profile_handler *pprof,return -EOPNOTSUPP ; } - asus->throttle_thermal_policy_mode =asus_wmi_platform_profile_to_vivo (asus, tp); + asus->throttle_thermal_policy_mode = tp;return throttle_thermal_policy_write (asus); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 28/356 platform/x86: asus-wmi: Ignore return value when writing thermal policy
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 25fb5f47f34d90aceda2c47a4230315536e97fa8 ]
On some machines like the ASUS Vivobook S14 writing the thermal policy returns the currently writen thermal policy instead of an error code.
Ignore the return code to avoid falsely returning an error when the thermal policy was written successfully.
--- drivers/platform/x86/asus-wmi.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-)
drivers/platform/x86/asus-wmi.c +2 -9
@@ -3386,7 +3386,6 @@ static int asus_wmi_custom_fan_curve_init(struct asus_wmi *asus)/* Throttle thermal policy ****************************************************/ static int throttle_thermal_policy_write (struct asus_wmi *asus) { -u32 retval;u8 value;int err;
@@ -3408,8 +3407,8 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus) value = asus->throttle_thermal_policy_mode; } - err =asus_wmi_set_devstate (asus->throttle_thermal_policy_dev, - value, &retval); +/* Some machines do not return an error code as a result, so we ignore it */ + err =asus_wmi_set_devstate (asus->throttle_thermal_policy_dev, value,NULL );sysfs_notify (&asus->platform_device->dev.kobj,NULL ,"throttle_thermal_policy" );
@@ -3419,12 +3418,6 @@ static int throttle_thermal_policy_write(struct asus_wmi *asus)return err; } -if (retval !=1 ) { -pr_warn ("Failed to set throttle thermal policy (retval): 0x%x\n" , - retval); -return -EIO ; - } -/* Must set to disabled if mode is toggled */ if (asus->cpu_fan_curve_available) asus->custom_fan_curves[FAN_CURVE_DEV_CPU ].enabled = false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 29/356 net-timestamp: make sk_tskey more predictable in error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vadim Fedorenko <[email protected]>
[ Upstream commit 488b6d91b07112eaaaa4454332c1480894d4e06e ]
When SOF_TIMESTAMPING_OPT_ID is used to ambiguate timestamped datagrams, the sk_tskey can become unpredictable in case of any error happened during sendmsg(). Move increment later in the code and make decrement of sk_tskey in error path. This solution is still racy in case of multiple threads doing snedmsg() over the very same socket in parallel, but still makes error path much more predictable.
Stable-dep-of: 3301ab7d5aeb ("net/ipv6: release expired exception dst cached in socket")
--- net/ipv4/ip_output.c | 13 ++++++++----- net/ipv6/ip6_output.c | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-)
net/ipv4/ip_output.c +8 -5
@@ -972,8 +972,8 @@ static int __ip_append_data(struct sock *sk,unsigned int maxfraglen, fragheaderlen, maxnonfragsize;int csummode =CHECKSUM_NONE ;struct rtable *rt = (struct rtable *)cork->dst; +bool paged, hold_tskey, extra_uref = false;unsigned int wmem_alloc_delta =0 ; -bool paged, extra_uref = false;u32 tskey =0 ; skb =skb_peek_tail (queue);
@@ -982,10 +982,6 @@ static int __ip_append_data(struct sock *sk, mtu = cork->gso_size ?IP_MAX_MTU : cork->fragsize; paged = !!cork->gso_size; -if (cork->tx_flags &SKBTX_ANY_TSTAMP && -READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ) - tskey =atomic_inc_return (&sk->sk_tskey) -1 ; - hh_len =LL_RESERVED_SPACE (rt->dst.dev); fragheaderlen =sizeof (struct iphdr ) + (opt ? opt->optlen :0 );
@@ -1052,6 +1048,11 @@ static int __ip_append_data(struct sock *sk, cork->length += length; + hold_tskey = cork->tx_flags &SKBTX_ANY_TSTAMP && +READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ; +if (hold_tskey) + tskey =atomic_inc_return (&sk->sk_tskey) -1 ; +/* So, what's going on in the loop below? * * We use calculated fragment length to generate chained skb,
@@ -1274,6 +1275,8 @@ static int __ip_append_data(struct sock *sk, cork->length -= length;IP_INC_STATS (sock_net (sk),IPSTATS_MIB_OUTDISCARDS );refcount_add (wmem_alloc_delta, &sk->sk_wmem_alloc); +if (hold_tskey) +atomic_dec (&sk->sk_tskey);return err; }
net/ipv6/ip6_output.c +8 -5
@@ -1501,11 +1501,11 @@ static int __ip6_append_data(struct sock *sk,bool zc = false;u32 tskey =0 ;struct rt6_info *rt = (struct rt6_info *)cork->dst; +bool paged, hold_tskey, extra_uref = false;struct ipv6_txoptions *opt = v6_cork->opt;int csummode =CHECKSUM_NONE ;unsigned int maxnonfragsize, headersize;unsigned int wmem_alloc_delta =0 ; -bool paged, extra_uref = false; skb =skb_peek_tail (queue);if (!skb) {
@@ -1517,10 +1517,6 @@ static int __ip6_append_data(struct sock *sk, mtu = cork->gso_size ?IP6_MAX_MTU : cork->fragsize; orig_mtu = mtu; -if (cork->tx_flags &SKBTX_ANY_TSTAMP && -READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ) - tskey =atomic_inc_return (&sk->sk_tskey) -1 ; - hh_len =LL_RESERVED_SPACE (rt->dst.dev); fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
@@ -1617,6 +1613,11 @@ static int __ip6_append_data(struct sock *sk, flags &= ~MSG_SPLICE_PAGES ; } + hold_tskey = cork->tx_flags &SKBTX_ANY_TSTAMP && +READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ; +if (hold_tskey) + tskey =atomic_inc_return (&sk->sk_tskey) -1 ; +/* * Let's try using as much space as possible. * Use MTU if total length of the message fits into the MTU.
@@ -1873,6 +1874,8 @@ static int __ip6_append_data(struct sock *sk, cork->length -= length;IP6_INC_STATS (sock_net (sk), rt->rt6i_idev,IPSTATS_MIB_OUTDISCARDS );refcount_add (wmem_alloc_delta, &sk->sk_wmem_alloc); +if (hold_tskey) +atomic_dec (&sk->sk_tskey);return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 30/356 ipv6: introduce dst_rt6_info() helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit e8dfd42c17faf183415323db1ef0c977be0d6489 ]
Instead of (struct rt6_info *)dst casts, we can use :
#define dst_rt6_info(_ptr) \
container_of_const(_ptr, struct rt6_info, dst)
Some places needed missing const qualifiers :
ip6_confirm_neigh(), ipv6_anycast_destination(),ipv6_unicast_destination(), has_gateway()
v2: added missing parts (David Ahern)
Stable-dep-of: 3301ab7d5aeb ("net/ipv6: release expired exception dst cached in socket")
--- drivers/infiniband/core/addr.c | 6 ++-- .../ethernet/mellanox/mlxsw/spectrum_span.c | 2 +- drivers/net/vrf.c | 2 +- drivers/net/vxlan/vxlan_core.c | 2 +- drivers/s390/net/qeth_core.h | 4 +-- include/net/ip6_fib.h | 6 ++-- include/net/ip6_route.h | 11 ++++---- net/bluetooth/6lowpan.c | 2 +- net/core/dst_cache.c | 2 +- net/core/filter.c | 2 +- net/ipv4/ip_tunnel.c | 2 +- net/ipv6/icmp.c | 8 +++--- net/ipv6/ila/ila_lwt.c | 4 +-- net/ipv6/ip6_output.c | 18 ++++++------ net/ipv6/ip6mr.c | 2 +- net/ipv6/ndisc.c | 2 +- net/ipv6/ping.c | 2 +- net/ipv6/raw.c | 4 +-- net/ipv6/route.c | 28 +++++++++---------- net/ipv6/tcp_ipv6.c | 4 +-- net/ipv6/udp.c | 11 +++----- net/ipv6/xfrm6_policy.c | 2 +- net/l2tp/l2tp_ip6.c | 2 +- net/mpls/mpls_iptunnel.c | 2 +- net/netfilter/ipvs/ip_vs_xmit.c | 14 +++++----- net/netfilter/nf_flow_table_core.c | 8 ++---- net/netfilter/nf_flow_table_ip.c | 4 +-- net/netfilter/nft_rt.c | 2 +- net/sctp/ipv6.c | 2 +- net/xfrm/xfrm_policy.c | 3 +- 30 files changed, 77 insertions(+), 86 deletions(-)
drivers/infiniband/core/addr.c +3 -3
@@ -348,15 +348,15 @@ static int dst_fetch_ha(const struct dst_entry *dst,static bool has_gateway (const struct dst_entry *dst,sa_family_t family) { -struct rtable *rt; -struct rt6_info *rt6; +const struct rtable *rt; +const struct rt6_info *rt6;if (family ==AF_INET ) { rt = container_of(dst, struct rtable, dst);return rt->rt_uses_gateway; } - rt6 = container_of(dst, struct rt6_info, dst); + rt6 =dst_rt6_info (dst);return rt6->rt6i_flags &RTF_GATEWAY ; }
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +1 -1
@@ -539,7 +539,7 @@ mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,if (!dst || dst->error) goto out; - rt6 = container_of(dst, struct rt6_info, dst); + rt6 =dst_rt6_info (dst); dev = dst->dev; *saddrp = fl6.saddr;
drivers/net/vrf.c +1 -1
@@ -655,7 +655,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, skb->dev = dev;rcu_read_lock (); - nexthop =rt6_nexthop ((struct rt6_info *)dst, &ipv6_hdr (skb)->daddr); + nexthop =rt6_nexthop (dst_rt6_info (dst), &ipv6_hdr (skb)->daddr); neigh =__ipv6_neigh_lookup_noref (dst->dev, nexthop);if (unlikely (!neigh)) neigh =__neigh_create (&nd_tbl, nexthop, dst->dev, false);
drivers/net/vxlan/vxlan_core.c +1 -1
@@ -2629,7 +2629,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, }if (!info) { -u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags; +u32 rt6i_flags =dst_rt6_info (ndst)->rt6i_flags; err = encap_bypass_if_local(skb, dev, vxlan, dst, dst_port, ifindex, vni,
drivers/s390/net/qeth_core.h +2 -2
@@ -956,7 +956,7 @@ static inline struct dst_entry *qeth_dst_check_rcu(struct sk_buff *skb,struct dst_entry *dst =skb_dst (skb);struct rt6_info *rt; - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst);if (dst) {if (proto ==htons (ETH_P_IPV6 )) dst =dst_check (dst,rt6_get_cookie (rt));
@@ -978,7 +978,7 @@ static inline __be32 qeth_next_hop_v4_rcu(struct sk_buff *skb,static inline struct in6_addr *qeth_next_hop_v6_rcu (struct sk_buff *skb,struct dst_entry *dst) { -struct rt6_info *rt = (struct rt6_info *) dst; +struct rt6_info *rt =dst_rt6_info (dst);if (rt && !ipv6_addr_any (&rt->rt6i_gateway))return &rt->rt6i_gateway;
include/net/ip6_fib.h +4 -2
@@ -237,9 +237,11 @@ struct fib6_result {for (rt = (w)->leaf; rt; \ rt = rcu_dereference_protected(rt->fib6_next, 1)) -static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) +#define dst_rt6_info (_ptr) container_of_const(_ptr, struct rt6_info, dst) + +static inline struct inet6_dev *ip6_dst_idev (const struct dst_entry *dst) { -return ((struct rt6_info *)dst)->rt6i_idev; +return dst_rt6_info (dst)->rt6i_idev; }static inline bool fib6_requires_src (const struct fib6_info *rt)
include/net/ip6_route.h +5 -6
@@ -218,12 +218,11 @@ void rt6_uncached_list_del(struct rt6_info *rt);static inline const struct rt6_info *skb_rt6_info (const struct sk_buff *skb) {const struct dst_entry *dst =skb_dst (skb); -const struct rt6_info *rt6 =NULL ;if (dst) - rt6 = container_of(dst, struct rt6_info, dst); +return dst_rt6_info (dst); -return rt6; +return NULL ; }/*
@@ -235,7 +234,7 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, {struct ipv6_pinfo *np =inet6_sk (sk); - np->dst_cookie =rt6_get_cookie ((struct rt6_info *)dst); + np->dst_cookie =rt6_get_cookie (dst_rt6_info (dst));sk_setup_caps (sk, dst); np->daddr_cache = daddr;#ifdef CONFIG_IPV6_SUBTREES
@@ -248,7 +247,7 @@ void ip6_sk_dst_store_flow(struct sock *sk, struct dst_entry *dst,static inline bool ipv6_unicast_destination (const struct sk_buff *skb) { -struct rt6_info *rt = (struct rt6_info *)skb_dst (skb); +const struct rt6_info *rt =dst_rt6_info (skb_dst (skb));return rt->rt6i_flags &RTF_LOCAL ; }
@@ -256,7 +255,7 @@ static inline bool ipv6_unicast_destination(const struct sk_buff *skb)static inline bool ipv6_anycast_destination (const struct dst_entry *dst,const struct in6_addr *daddr) { -struct rt6_info *rt = (struct rt6_info *)dst; +const struct rt6_info *rt =dst_rt6_info (dst); return rt->rt6i_flags & RTF_ANYCAST || (rt->rt6i_dst.plen < 127 &&
net/bluetooth/6lowpan.c +1 -1
@@ -133,7 +133,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,struct in6_addr *daddr, struct sk_buff *skb) { - struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); + struct rt6_info *rt = dst_rt6_info(skb_dst(skb));int count =atomic_read (&dev->peer_count);const struct in6_addr *nexthop;struct lowpan_peer *peer;
net/core/dst_cache.c +1 -1
@@ -112,7 +112,7 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, idst =this_cpu_ptr (dst_cache->cache);dst_cache_per_cpu_dst_set (this_cpu_ptr (dst_cache->cache), dst, -rt6_get_cookie ((struct rt6_info *)dst)); +rt6_get_cookie (dst_rt6_info (dst))); idst->in6_saddr = *saddr; }EXPORT_SYMBOL_GPL (dst_cache_set_ip6);
net/core/filter.c +1 -1
@@ -2215,7 +2215,7 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,rcu_read_lock ();if (!nh) { dst =skb_dst (skb); - nexthop = rt6_nexthop(container_of(dst, struct rt6_info, dst), + nexthop =rt6_nexthop (dst_rt6_info (dst), &ipv6_hdr (skb)->daddr); }else { nexthop = &nh->ipv6_nh;
net/ipv4/ip_tunnel.c +1 -1
@@ -544,7 +544,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb,struct rt6_info *rt6;__be32 daddr; - rt6 =skb_valid_dst (skb) ? (struct rt6_info *)skb_dst (skb) : + rt6 =skb_valid_dst (skb) ?dst_rt6_info (skb_dst (skb)) :NULL ; daddr = md ? dst : tunnel->parms.iph.daddr;
net/ipv6/icmp.c +4 -4
@@ -214,7 +214,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, }else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK )) { res = true; }else { -struct rt6_info *rt = (struct rt6_info *)dst; +struct rt6_info *rt =dst_rt6_info (dst);int tmo = net->ipv6.sysctl.icmpv6_time;struct inet_peer *peer;
@@ -245,7 +245,7 @@ static bool icmpv6_rt_has_prefsrc(struct sock *sk, u8 type, dst =ip6_route_output (net, sk, fl6);if (!dst->error) { -struct rt6_info *rt = (struct rt6_info *)dst; +struct rt6_info *rt =dst_rt6_info (dst);struct in6_addr prefsrc;rt6_get_prefsrc (rt, &prefsrc);
@@ -622,7 +622,7 @@ void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,if (ip6_append_data (sk, icmpv6_getfrag, &msg, len +sizeof (struct icmp6hdr ),sizeof (struct icmp6hdr ), - &ipc6, &fl6, (struct rt6_info *)dst, + &ipc6, &fl6,dst_rt6_info (dst),MSG_DONTWAIT )) {ICMP6_INC_STATS (net, idev,ICMP6_MIB_OUTERRORS );ip6_flush_pending_frames (sk);
@@ -811,7 +811,7 @@ static enum skb_drop_reason icmpv6_echo_reply(struct sk_buff *skb)if (ip6_append_data (sk, icmpv6_getfrag, &msg, skb->len +sizeof (struct icmp6hdr ),sizeof (struct icmp6hdr ), &ipc6, &fl6, - (struct rt6_info *)dst,MSG_DONTWAIT )) { +dst_rt6_info (dst),MSG_DONTWAIT )) {__ICMP6_INC_STATS (net, idev,ICMP6_MIB_OUTERRORS );ip6_flush_pending_frames (sk); }else {
net/ipv6/ila/ila_lwt.c +2 -2
@@ -38,7 +38,7 @@ static inline struct ila_params *ila_params_lwtunnel(static int ila_output (struct net *net,struct sock *sk,struct sk_buff *skb) {struct dst_entry *orig_dst =skb_dst (skb); -struct rt6_info *rt = (struct rt6_info *)orig_dst; +struct rt6_info *rt =dst_rt6_info (orig_dst);struct ila_lwt *ilwt =ila_lwt_lwtunnel (orig_dst->lwtstate);struct dst_entry *dst;int err = -EINVAL ;
@@ -72,7 +72,7 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)memset (&fl6,0 ,sizeof (fl6)); fl6.flowi6_oif = orig_dst->dev->ifindex; fl6.flowi6_iif =LOOPBACK_IFINDEX ; - fl6.daddr = *rt6_nexthop ((struct rt6_info *)orig_dst, + fl6.daddr = *rt6_nexthop (dst_rt6_info (orig_dst), &ip6h->daddr); dst =ip6_route_output (net,NULL , &fl6);
net/ipv6/ip6_output.c +9 -9
@@ -124,7 +124,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *IP6_UPD_PO_STATS (net, idev,IPSTATS_MIB_OUT , skb->len);rcu_read_lock (); - nexthop =rt6_nexthop ((struct rt6_info *)dst, daddr); + nexthop =rt6_nexthop (dst_rt6_info (dst), daddr); neigh =__ipv6_neigh_lookup_noref (dev, nexthop);if (unlikely (IS_ERR_OR_NULL (neigh))) {
@@ -606,7 +606,7 @@ int ip6_forward(struct sk_buff *skb)* send a redirect. */ - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst);if (rt->rt6i_flags &RTF_GATEWAY ) target = &rt->rt6i_gateway;else
@@ -861,7 +861,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, int (*output)(struct net *, struct sock *, struct sk_buff *)) {struct sk_buff *frag; -struct rt6_info *rt = (struct rt6_info *)skb_dst (skb); +struct rt6_info *rt =dst_rt6_info (skb_dst (skb));struct ipv6_pinfo *np = skb->sk && !dev_recursion_level () ?inet6_sk (skb->sk) :NULL ;bool mono_delivery_time = skb->mono_delivery_time;
@@ -1069,7 +1069,7 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,return NULL ; } - rt = (struct rt6_info *)dst; + rt =dst_rt6_info (dst);/* Yes, checking route validity in not connected * case is not very simple. Take into account, * that we do not support routing by source, TOS,
@@ -1124,7 +1124,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,struct rt6_info *rt; *dst =ip6_route_output (net, sk, fl6); - rt = (*dst)->error ?NULL : (struct rt6_info *)*dst; + rt = (*dst)->error ?NULL :dst_rt6_info (*dst);rcu_read_lock (); from = rt ?rcu_dereference (rt->from) :NULL ;
@@ -1166,7 +1166,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,* dst entry and replace it instead with the * dst entry of the nexthop router */ - rt = (struct rt6_info *) *dst; + rt =dst_rt6_info (*dst);rcu_read_lock (); n =__ipv6_neigh_lookup_noref (rt->dst.dev,rt6_nexthop (rt, &fl6->daddr));
@@ -1500,7 +1500,7 @@ static int __ip6_append_data(struct sock *sk,int offset =0 ;bool zc = false;u32 tskey =0 ; -struct rt6_info *rt = (struct rt6_info *)cork->dst; +struct rt6_info *rt =dst_rt6_info (cork->dst);bool paged, hold_tskey, extra_uref = false;struct ipv6_txoptions *opt = v6_cork->opt;int csummode =CHECKSUM_NONE ;
@@ -1959,7 +1959,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,struct net *net =sock_net (sk);struct ipv6hdr *hdr;struct ipv6_txoptions *opt = v6_cork->opt; -struct rt6_info *rt = (struct rt6_info *)cork->base.dst; +struct rt6_info *rt =dst_rt6_info (cork->base.dst);struct flowi6 *fl6 = &cork->fl.u.ip6;unsigned char proto = fl6->flowi6_proto;
@@ -2031,7 +2031,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,int ip6_send_skb (struct sk_buff *skb) {struct net *net =sock_net (skb->sk); -struct rt6_info *rt = (struct rt6_info *)skb_dst (skb); +struct rt6_info *rt =dst_rt6_info (skb_dst (skb));int err;rcu_read_lock ();
net/ipv6/ip6mr.c +1 -1
@@ -2290,7 +2290,7 @@ int ip6mr_get_route(struct net *net, struct sk_buff *skb, struct rtmsg *rtm,int err;struct mr_table *mrt;struct mfc6_cache *cache; -struct rt6_info *rt = (struct rt6_info *)skb_dst (skb); +struct rt6_info *rt =dst_rt6_info (skb_dst (skb));rcu_read_lock (); mrt =__ip6mr_get_table (net,RT6_TABLE_DFLT );
net/ipv6/ndisc.c +1 -1
@@ -1710,7 +1710,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)if (IS_ERR (dst))return ; - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst);if (rt->rt6i_flags &RTF_GATEWAY ) { ND_PRINTK(2, warn,
net/ipv6/ping.c +1 -1
@@ -154,7 +154,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) dst =ip6_sk_dst_lookup_flow (sk, &fl6, daddr, false);if (IS_ERR (dst))return PTR_ERR (dst); - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst);if (!fl6.flowi6_oif &&ipv6_addr_is_multicast (&fl6.daddr)) fl6.flowi6_oif = np->mcast_oif;
net/ipv6/raw.c +2 -2
@@ -592,7 +592,7 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,struct ipv6hdr *iph;struct sk_buff *skb;int err; -struct rt6_info *rt = (struct rt6_info *)*dstp; +struct rt6_info *rt =dst_rt6_info (*dstp);int hlen =LL_RESERVED_SPACE (rt->dst.dev);int tlen = rt->dst.dev->needed_tailroom;
@@ -911,7 +911,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ipc6.opt = opt;lock_sock (sk); err =ip6_append_data (sk, raw6_getfrag, &rfv, - len,0 , &ipc6, &fl6, (struct rt6_info *)dst, + len,0 , &ipc6, &fl6,dst_rt6_info (dst), msg->msg_flags);if (err)
net/ipv6/route.c +14 -14
@@ -227,7 +227,7 @@ static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst,struct sk_buff *skb, const void *daddr) { - const struct rt6_info *rt = container_of(dst, struct rt6_info, dst); + const struct rt6_info *rt = dst_rt6_info(dst);return ip6_neigh_lookup (rt6_nexthop (rt, &in6addr_any), dst->dev, skb, daddr);
@@ -235,8 +235,8 @@ static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst,static void ip6_confirm_neigh (const struct dst_entry *dst,const void *daddr) { +const struct rt6_info *rt =dst_rt6_info (dst);struct net_device *dev = dst->dev; -struct rt6_info *rt = (struct rt6_info *)dst; daddr =choose_neigh_daddr (rt6_nexthop (rt, &in6addr_any),NULL , daddr);if (!daddr)
@@ -355,7 +355,7 @@ EXPORT_SYMBOL(ip6_dst_alloc);static void ip6_dst_destroy (struct dst_entry *dst) { -struct rt6_info *rt = (struct rt6_info *)dst; +struct rt6_info *rt =dst_rt6_info (dst);struct fib6_info *from;struct inet6_dev *idev;
@@ -374,7 +374,7 @@ static void ip6_dst_destroy(struct dst_entry *dst)static void ip6_dst_ifdown (struct dst_entry *dst,struct net_device *dev) { -struct rt6_info *rt = (struct rt6_info *)dst; +struct rt6_info *rt =dst_rt6_info (dst);struct inet6_dev *idev = rt->rt6i_idev;struct fib6_info *from;
@@ -1284,7 +1284,7 @@ struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr, dst =fib6_rule_lookup (net, &fl6, skb, flags, ip6_pol_route_lookup);if (dst->error ==0 ) -return (struct rt6_info *) dst; +return dst_rt6_info (dst);dst_release (dst);
@@ -2641,7 +2641,7 @@ struct dst_entry *ip6_route_output_flags(struct net *net,rcu_read_lock (); dst =ip6_route_output_flags_noref (net, sk, fl6, flags); - rt6 = (struct rt6_info *)dst; + rt6 =dst_rt6_info (dst);/* For dst cached in uncached_list, refcnt is already taken. */ if (list_empty (&rt6->dst.rt_uncached) && !dst_hold_safe (dst)) { dst = &net->ipv6.ip6_null_entry->dst;
@@ -2655,7 +2655,7 @@ EXPORT_SYMBOL_GPL(ip6_route_output_flags);struct dst_entry *ip6_blackhole_route (struct net *net,struct dst_entry *dst_orig) { -struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig; +struct rt6_info *rt, *ort =dst_rt6_info (dst_orig);struct net_device *loopback_dev = net->loopback_dev;struct dst_entry *new =NULL ;
@@ -2738,7 +2738,7 @@ INDIRECT_CALLABLE_SCOPE struct dst_entry *ip6_dst_check(struct dst_entry *dst,struct fib6_info *from;struct rt6_info *rt; - rt = container_of(dst, struct rt6_info, dst); + rt =dst_rt6_info (dst);if (rt->sernum)return rt6_is_valid (rt) ? dst :NULL ;
@@ -2767,7 +2767,7 @@ EXPORT_INDIRECT_CALLABLE(ip6_dst_check);static void ip6_negative_advice (struct sock *sk,struct dst_entry *dst) { -struct rt6_info *rt = (struct rt6_info *) dst; +struct rt6_info *rt =dst_rt6_info (dst);if (rt->rt6i_flags &RTF_CACHE ) {rcu_read_lock ();
@@ -2790,7 +2790,7 @@ static void ip6_link_failure(struct sk_buff *skb)icmpv6_send (skb,ICMPV6_DEST_UNREACH ,ICMPV6_ADDR_UNREACH ,0 ); - rt = (struct rt6_info *)skb_dst (skb); + rt =dst_rt6_info (skb_dst (skb));if (rt) {rcu_read_lock ();if (rt->rt6i_flags &RTF_CACHE ) {
@@ -2846,7 +2846,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, bool confirm_neigh) {const struct in6_addr *daddr, *saddr; -struct rt6_info *rt6 = (struct rt6_info *)dst; +struct rt6_info *rt6 =dst_rt6_info (dst);/* Note: do *NOT* check dst_metric_locked(dst, RTAX_MTU) * IPv6 pmtu discovery isn't optional, so 'mtu lock' cannot disable it.
@@ -4169,7 +4169,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu } } - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst);if (rt->rt6i_flags &RTF_REJECT ) {net_dbg_ratelimited ("rt6_redirect: source isn't a valid nexthop for redirect target\n" );return ;
@@ -5604,7 +5604,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, int iif, int type, u32 portid, u32 seq, unsigned int flags) { - struct rt6_info *rt6 = (struct rt6_info *)dst; + struct rt6_info *rt6 = dst_rt6_info(dst);struct rt6key *rt6_dst, *rt6_src;u32 *pmetrics, table, rt6_flags;unsigned char nh_flags =0 ;
@@ -6107,7 +6107,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, } - rt = container_of(dst, struct rt6_info, dst); + rt =dst_rt6_info (dst);if (rt->dst.error) { err = rt->dst.error;ip6_rt_put (rt);
net/ipv6/tcp_ipv6.c +1 -3
@@ -101,11 +101,9 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)struct dst_entry *dst =skb_dst (skb);if (dst &&dst_hold_safe (dst)) { -const struct rt6_info *rt = (const struct rt6_info *)dst; -rcu_assign_pointer (sk->sk_rx_dst, dst); sk->sk_rx_dst_ifindex = skb->skb_iif; - sk->sk_rx_dst_cookie =rt6_get_cookie (rt); + sk->sk_rx_dst_cookie =rt6_get_cookie (dst_rt6_info (dst)); } }
net/ipv6/udp.c +4 -7
@@ -913,11 +913,8 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,static void udp6_sk_rx_dst_set (struct sock *sk,struct dst_entry *dst) { -if (udp_sk_rx_dst_set (sk, dst)) { -const struct rt6_info *rt = (const struct rt6_info *)dst; - - sk->sk_rx_dst_cookie =rt6_get_cookie (rt); - } +if (udp_sk_rx_dst_set (sk, dst)) + sk->sk_rx_dst_cookie =rt6_get_cookie (dst_rt6_info (dst)); }/* wrapper for udp_queue_rcv_skb tacking care of csum conversion and
@@ -1587,7 +1584,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) skb =ip6_make_skb (sk, getfrag, msg, ulen,sizeof (struct udphdr ), &ipc6, - (struct rt6_info *)dst, +dst_rt6_info (dst), msg->msg_flags, &cork); err =PTR_ERR (skb);if (!IS_ERR_OR_NULL (skb))
@@ -1614,7 +1611,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ipc6.dontfrag = np->dontfrag; up->len += ulen; err =ip6_append_data (sk, getfrag, msg, ulen,sizeof (struct udphdr ), - &ipc6, fl6, (struct rt6_info *)dst, + &ipc6, fl6,dst_rt6_info (dst), corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);if (err)udp_v6_flush_pending_frames (sk);
net/ipv6/xfrm6_policy.c +1 -1
@@ -77,7 +77,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr,static int xfrm6_fill_dst (struct xfrm_dst *xdst,struct net_device *dev,const struct flowi *fl) { -struct rt6_info *rt = (struct rt6_info *)xdst->route; +struct rt6_info *rt =dst_rt6_info (xdst->route); xdst->u.dst.dev = dev;netdev_hold (dev, &xdst->u.dst.dev_tracker,GFP_ATOMIC );
net/l2tp/l2tp_ip6.c +1 -1
@@ -630,7 +630,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) ulen = len + (skb_queue_empty (&sk->sk_write_queue) ? transhdrlen :0 ); err =ip6_append_data (sk, ip_generic_getfrag, msg, ulen, transhdrlen, &ipc6, - &fl6, (struct rt6_info *)dst, + &fl6,dst_rt6_info (dst), msg->msg_flags);if (err)ip6_flush_pending_frames (sk);
net/mpls/mpls_iptunnel.c +1 -1
@@ -92,7 +92,7 @@ static int mpls_xmit(struct sk_buff *skb) ttl = net->mpls.default_ttl; else ttl =ipv6_hdr (skb)->hop_limit; - rt6 = (struct rt6_info *)dst; + rt6 =dst_rt6_info (dst); }else { goto drop; }
net/netfilter/ipvs/ip_vs_xmit.c +7 -7
@@ -180,7 +180,7 @@ static inline bool crosses_local_route_boundary(int skb_af, struct sk_buff *skb, (!skb->dev || skb->dev->flags &IFF_LOOPBACK ) && (addr_type &IPV6_ADDR_LOOPBACK ); old_rt_is_local =__ip_vs_is_local_route6 ( - (struct rt6_info *)skb_dst (skb)); +dst_rt6_info (skb_dst (skb))); } else#endif {
@@ -481,7 +481,7 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,if (dest) { dest_dst =__ip_vs_dst_check (dest);if (likely (dest_dst)) - rt = (struct rt6_info *) dest_dst->dst_cache; + rt =dst_rt6_info (dest_dst->dst_cache);else {u32 cookie;
@@ -501,7 +501,7 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,ip_vs_dest_dst_free (dest_dst); goto err_unreach; } - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst); cookie =rt6_get_cookie (rt);__ip_vs_dst_set (dest, dest_dst, &rt->dst, cookie);spin_unlock_bh (&dest->dst_lock);
@@ -517,7 +517,7 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, rt_mode);if (!dst) goto err_unreach; - rt = (struct rt6_info *) dst; + rt =dst_rt6_info (dst); } local =__ip_vs_is_local_route6 (rt);
@@ -862,7 +862,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_RT_MODE_RDR);if (local <0 ) goto tx_error; - rt = (struct rt6_info *)skb_dst (skb); + rt =dst_rt6_info (skb_dst (skb));/* * Avoid duplicate tuple in reply direction for NAT traffic * to local address when connection is sync-ed
@@ -1288,7 +1288,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,if (local)return ip_vs_send_or_cont (NFPROTO_IPV6 , skb, cp,1 ); - rt = (struct rt6_info *)skb_dst (skb); + rt =dst_rt6_info (skb_dst (skb)); tdev = rt->dst.dev;/*
@@ -1590,7 +1590,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, &cp->daddr.in6, NULL, ipvsh, 0, rt_mode);if (local <0 ) goto tx_error; - rt = (struct rt6_info *)skb_dst (skb); + rt =dst_rt6_info (skb_dst (skb));/* * Avoid duplicate tuple in reply direction for NAT traffic * to local address when connection is sync-ed
net/netfilter/nf_flow_table_core.c +2 -6
@@ -77,12 +77,8 @@ EXPORT_SYMBOL_GPL(flow_offload_alloc);static u32 flow_offload_dst_cookie (struct flow_offload_tuple *flow_tuple) { -const struct rt6_info *rt; - -if (flow_tuple->l3proto ==NFPROTO_IPV6 ) { - rt = (const struct rt6_info *)flow_tuple->dst_cache; -return rt6_get_cookie (rt); - } +if (flow_tuple->l3proto ==NFPROTO_IPV6 ) +return rt6_get_cookie (dst_rt6_info (flow_tuple->dst_cache));return 0 ; }
net/netfilter/nf_flow_table_ip.c +2 -2
@@ -732,7 +732,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,return NF_ACCEPT ;if (unlikely (tuplehash->tuple.xmit_type ==FLOW_OFFLOAD_XMIT_XFRM )) { - rt = (struct rt6_info *)tuplehash->tuple.dst_cache; + rt =dst_rt6_info (tuplehash->tuple.dst_cache);memset (skb->cb,0 ,sizeof (struct inet6_skb_parm ));IP6CB (skb)->iif = skb->dev->ifindex;IP6CB (skb)->flags =IP6SKB_FORWARDED ;
@@ -744,7 +744,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,switch (tuplehash->tuple.xmit_type) {case FLOW_OFFLOAD_XMIT_NEIGH : - rt = (struct rt6_info *)tuplehash->tuple.dst_cache; + rt =dst_rt6_info (tuplehash->tuple.dst_cache); outdev = rt->dst.dev; skb->dev = outdev; nexthop =rt6_nexthop (rt, &flow->tuplehash[!dir].tuple.src_v6);
net/netfilter/nft_rt.c +1 -1
@@ -80,7 +80,7 @@ void nft_rt_get_eval(const struct nft_expr *expr,if (nft_pf (pkt) !=NFPROTO_IPV6 ) goto err; -memcpy (dest,rt6_nexthop ((struct rt6_info *)dst, +memcpy (dest,rt6_nexthop (dst_rt6_info (dst), &ipv6_hdr (skb)->daddr),sizeof (struct in6_addr ));break ;
net/sctp/ipv6.c +1 -1
@@ -416,7 +416,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,if (!IS_ERR_OR_NULL (dst)) {struct rt6_info *rt; - rt = (struct rt6_info *)dst; + rt =dst_rt6_info (dst); t->dst_cookie =rt6_get_cookie (rt); pr_debug("rt6_dst:%pI6/%d rt6_src:%pI6\n", &rt->rt6i_dst.addr, rt->rt6i_dst.plen,
net/xfrm/xfrm_policy.c +1 -2
@@ -2607,8 +2607,7 @@ static void xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst, int nfheader_len) {if (dst->ops->family ==AF_INET6 ) { -struct rt6_info *rt = (struct rt6_info *)dst; - path->path_cookie =rt6_get_cookie (rt); + path->path_cookie =rt6_get_cookie (dst_rt6_info (dst)); path->u.rt6.rt6i_nfheader_len = nfheader_len; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 31/356 net/ipv6: release expired exception dst cached in socket
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Wiesner <[email protected]>
[ Upstream commit 3301ab7d5aeb0fe270f73a3d4810c9d1b6a9f045 ]
Dst objects get leaked in ip6_negative_advice() when this function is executed for an expired IPv6 route located in the exception table. There are several conditions that must be fulfilled for the leak to occur:
* an ICMPv6 packet indicating a change of the MTU for the path is received, resulting in an exception dst being created
* a TCP connection that uses the exception dst for routing packets must start timing out so that TCP begins retransmissions
* after the exception dst expires, the FIB6 garbage collector must not run before TCP executes ip6_negative_advice() for the expired exception dst
When TCP executes ip6_negative_advice() for an exception dst that has expired and if no other socket holds a reference to the exception dst, the refcount of the exception dst is 2, which corresponds to the increment made by dst_init() and the increment made by the TCP socket for which the connection is timing out. The refcount made by the socket is never released. The refcount of the dst is decremented in sk_dst_reset() but that decrement is counteracted by a dst_hold() intentionally placed just before the sk_dst_reset() in ip6_negative_advice(). After ip6_negative_advice() has finished, there is no other object tied to the dst. The socket lost its reference stored in sk_dst_cache and the dst is no longer in the exception table. The exception dst becomes a leaked object.
As a result of this dst leak, an unbalanced refcount is reported for the loopback device of a net namespace being destroyed under kernels that do not contain e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"):unregister_netdevice: waiting for lo to become free. Usage count = 2
Fix the dst leak by removing the dst_hold() in ip6_negative_advice(). The patch that introduced the dst_hold() in ip6_negative_advice() was 92f1655aa2b22 ("net: fix __dst_negative_advice() race"). But 92f1655aa2b22 merely refactored the code with regards to the dst refcount so the issue was present even before 92f1655aa2b22. The bug was introduced in 54c1a859efd9f ("ipv6: Don't drop cache route entry unless timer actually expired.") where the expired cached route is deleted and the sk_dst_cache member of the socket is set to NULL by calling dst_negative_advice() but the refcount belonging to the socket is left unbalanced.
The IPv4 version - ipv4_negative_advice() - is not affected by this bug. When the TCP connection times out ipv4_negative_advice() merely resets the sk_dst_cache of the socket while decrementing the refcount of the exception dst.
--- net/ipv6/route.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv6/route.c +3 -3
@@ -2772,10 +2772,10 @@ static void ip6_negative_advice(struct sock *sk,if (rt->rt6i_flags &RTF_CACHE ) {rcu_read_lock ();if (rt6_check_expired (rt)) { -/* counteract the dst_release() in sk_dst_reset() */ -dst_hold (dst); +/* rt/dst can not be destroyed yet, +* because of rcu_read_lock() +*/ sk_dst_reset (sk); -rt6_remove_exception_rt (rt); }rcu_read_unlock ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 32/356 dccp: Fix memory leak in dccp_feat_change_recv
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Solodovnikov <[email protected]>
[ Upstream commit 22be4727a8f898442066bcac34f8a1ad0bc72e14 ]
If dccp_feat_push_confirm() fails after new value for SP feature was accepted without reconciliation ('entry == NULL' branch), memory allocated for that value with dccp_feat_clone_sp_val() is never freed.
Here is the kmemleak stack for this:
unreferenced object 0xffff88801d4ab488 (size 8):
comm "syz-executor310", pid 1127, jiffies 4295085598 (age 41.666s) hex dump (first 8 bytes):
01 b4 4a 1d 80 88 ff ff ..J.....
backtrace:
[<00000000db7cabfe>] kmemdup+0x23/0x50 mm/util.c:128
[<0000000019b38405>] kmemdup include/linux/string.h:465 [inline]
[<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:371 [inline]
[<0000000019b38405>] dccp_feat_clone_sp_val net/dccp/feat.c:367 [inline]
[<0000000019b38405>] dccp_feat_change_recv net/dccp/feat.c:1145 [inline]
[<0000000019b38405>] dccp_feat_parse_options+0x1196/0x2180 net/dccp/feat.c:1416
[<00000000b1f6d94a>] dccp_parse_options+0xa2a/0x1260 net/dccp/options.c:125
[<0000000030d7b621>] dccp_rcv_state_process+0x197/0x13d0 net/dccp/input.c:650
[<000000001f74c72e>] dccp_v4_do_rcv+0xf9/0x1a0 net/dccp/ipv4.c:688
[<00000000a6c24128>] sk_backlog_rcv include/net/sock.h:1041 [inline]
[<00000000a6c24128>] __release_sock+0x139/0x3b0 net/core/sock.c:2570
[<00000000cf1f3a53>] release_sock+0x54/0x1b0 net/core/sock.c:3111
[<000000008422fa23>] inet_wait_for_connect net/ipv4/af_inet.c:603 [inline]
[<000000008422fa23>] __inet_stream_connect+0x5d0/0xf70 net/ipv4/af_inet.c:696
[<0000000015b6f64d>] inet_stream_connect+0x53/0xa0 net/ipv4/af_inet.c:735
[<0000000010122488>] __sys_connect_file+0x15c/0x1a0 net/socket.c:1865
[<00000000b4b70023>] __sys_connect+0x165/0x1a0 net/socket.c:1882
[<00000000f4cb3815>] __do_sys_connect net/socket.c:1892 [inline]
[<00000000f4cb3815>] __se_sys_connect net/socket.c:1889 [inline]
[<00000000f4cb3815>] __x64_sys_connect+0x6e/0xb0 net/socket.c:1889
[<00000000e7b1e839>] do_syscall_64+0x33/0x40 arch/x86/entry/common.c:46
[<0000000055e91434>] entry_SYSCALL_64_after_hwframe+0x67/0xd1Clean up the allocated memory in case of dccp_feat_push_confirm() failure and bail out with an error reset code.
Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
--- net/dccp/feat.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/dccp/feat.c +5 -1
@@ -1166,8 +1166,12 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, goto not_valid_or_not_known; } -return dccp_feat_push_confirm (fn, feat, local, &fval); +if (dccp_feat_push_confirm (fn, feat, local, &fval)) { +kfree (fval.sp.vec); +return DCCP_RESET_CODE_TOO_BUSY ; + } +return 0 ; }else if (entry->state ==FEAT_UNSTABLE ) {/* 6.6.2 */ return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 33/356 tipc: Fix use-after-free of kernel socket in cleanup_bearer().
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 6a2fa13312e51a621f652d522d7e2df7066330b6 ]
syzkaller reported a use-after-free of UDP kernel socket in cleanup_bearer() without repro. [0][1]
When bearer_disable() calls tipc_udp_disable(), cleanup of the UDP kernel socket is deferred by work calling cleanup_bearer().
tipc_net_stop() waits for such works to finish by checking tipc_net(net)->wq_count. However, the work decrements the count too early before releasing the kernel socket, unblocking cleanup_net() and resulting in use-after-free.
Let's move the decrement after releasing the socket in cleanup_bearer().
[0]:ref_tracker: net notrefcnt@000000009b3d1faf has 1/1 users at
sk_alloc+0x438/0x608
inet_create+0x4c8/0xcb0
__sock_create+0x350/0x6b8
sock_create_kern+0x58/0x78
udp_sock_create4+0x68/0x398
udp_sock_create+0x88/0xc8
tipc_udp_enable+0x5e8/0x848
__tipc_nl_bearer_enable+0x84c/0xed8
tipc_nl_bearer_enable+0x38/0x60
genl_family_rcv_msg_doit+0x170/0x248
genl_rcv_msg+0x400/0x5b0
netlink_rcv_skb+0x1dc/0x398
genl_rcv+0x44/0x68
netlink_unicast+0x678/0x8b0
netlink_sendmsg+0x5e4/0x898
____sys_sendmsg+0x500/0x830[1]:
BUG: KMSAN: use-after-free in udp_hashslot include/net/udp.h:85 [inline] BUG: KMSAN: use-after-free in udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 udp_hashslot include/net/udp.h:85 [inline] udp_lib_unhash+0x3b8/0x930 net/ipv4/udp.c:1979 sk_common_release+0xaf/0x3f0 net/core/sock.c:3820 inet_release+0x1e0/0x260 net/ipv4/af_inet.c:437 inet6_release+0x6f/0xd0 net/ipv6/af_inet6.c:489 __sock_release net/socket.c:658 [inline] sock_release+0xa0/0x210 net/socket.c:686 cleanup_bearer+0x42d/0x4c0 net/tipc/udp_media.c:819 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 kthread+0x531/0x6b0 kernel/kthread.c:389 ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244
Uninit was created at:
slab_free_hook mm/slub.c:2269 [inline] slab_free mm/slub.c:4580 [inline] kmem_cache_free+0x207/0xc40 mm/slub.c:4682 net_free net/core/net_namespace.c:454 [inline] cleanup_net+0x16f2/0x19d0 net/core/net_namespace.c:647 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xcaf/0x1c90 kernel/workqueue.c:3310 worker_thread+0xf6c/0x1510 kernel/workqueue.c:3391 kthread+0x531/0x6b0 kernel/kthread.c:389 ret_from_fork+0x60/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:244 CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.12.0-rc1-00131-gf66ebf37d69c #7 91723d6f74857f70725e1583cba3cf4adc716cfa Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 Workqueue: events cleanup_bearer
--- net/tipc/udp_media.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/tipc/udp_media.c +1 -1
@@ -814,10 +814,10 @@ static void cleanup_bearer(struct work_struct *work)kfree_rcu (rcast, rcu); } -atomic_dec (&tipc_net (sock_net (ub->ubsock->sk))->wq_count);dst_cache_destroy (&ub->rcast.dst_cache);udp_tunnel_sock_release (ub->ubsock);synchronize_net (); +atomic_dec (&tipc_net (sock_net (ub->ubsock->sk))->wq_count);kfree (ub); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 34/356 net/smc: rename some fce to fce_v2x for clarity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit ac053a169c71ceb0f25f784fce9ea720455097b4 ]
Rename some functions or variables with 'fce' in their name but used in SMCv2.1 as 'fce_v2x' for clarity.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/smc_clc.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
net/smc/smc_clc.c +16 -14
@@ -428,15 +428,16 @@ smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)return true; } -static int smc_clc_fill_fce (struct smc_clc_first_contact_ext_v2x *fce, -struct smc_init_info *ini) +static int smc_clc_fill_fce_v2x (struct smc_clc_first_contact_ext_v2x *fce_v2x, +struct smc_init_info *ini) { -int ret =sizeof (*fce); +int ret =sizeof (*fce_v2x); -memset (fce,0 ,sizeof (*fce)); - fce->fce_v2_base.os_type =SMC_CLC_OS_LINUX ; - fce->fce_v2_base.release = ini->release_nr; -memcpy (fce->fce_v2_base.hostname, smc_hostname,sizeof (smc_hostname)); +memset (fce_v2x,0 ,sizeof (*fce_v2x)); + fce_v2x->fce_v2_base.os_type =SMC_CLC_OS_LINUX ; + fce_v2x->fce_v2_base.release = ini->release_nr; +memcpy (fce_v2x->fce_v2_base.hostname, + smc_hostname,sizeof (smc_hostname));if (ini->is_smcd && ini->release_nr <SMC_RELEASE_1 ) { ret =sizeof (struct smc_clc_first_contact_ext ); goto out;
@@ -444,8 +445,8 @@ static int smc_clc_fill_fce(struct smc_clc_first_contact_ext_v2x *fce,if (ini->release_nr >=SMC_RELEASE_1 ) {if (!ini->is_smcd) { - fce->max_conns = ini->max_conns; - fce->max_links = ini->max_links; + fce_v2x->max_conns = ini->max_conns; + fce_v2x->max_links = ini->max_links; } }
@@ -1012,8 +1013,8 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, int first_contact, u8 version, u8 *eid, struct smc_init_info *ini) { + struct smc_clc_first_contact_ext_v2x fce_v2x;struct smc_connection *conn = &smc->conn; -struct smc_clc_first_contact_ext_v2x fce;struct smcd_dev *smcd = conn->lgr->smcd;struct smc_clc_msg_accept_confirm *clc;struct smc_clc_fce_gid_ext gle;
@@ -1045,7 +1046,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,memcpy (clc_v2->d1.eid, eid,SMC_MAX_EID_LEN ); len =SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 ;if (first_contact) { - fce_len =smc_clc_fill_fce (&fce, ini); + fce_len =smc_clc_fill_fce_v2x (&fce_v2x, ini); len += fce_len; } clc_v2->hdr.length =htons (len);
@@ -1091,9 +1092,10 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,memcpy (clc_v2->r1.eid, eid,SMC_MAX_EID_LEN ); len =SMCR_CLC_ACCEPT_CONFIRM_LEN_V2 ;if (first_contact) { - fce_len =smc_clc_fill_fce (&fce, ini); + fce_len =smc_clc_fill_fce_v2x (&fce_v2x, ini); len += fce_len; - fce.fce_v2_base.v2_direct = !link->lgr->uses_gateway; + fce_v2x.fce_v2_base.v2_direct = + !link->lgr->uses_gateway;if (clc->hdr.type ==SMC_CLC_CONFIRM ) {memset (&gle,0 ,sizeof (gle)); gle.gid_cnt = ini->smcrv2.gidlist.len;
@@ -1120,7 +1122,7 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, SMCR_CLC_ACCEPT_CONFIRM_LEN) -sizeof (trl);if (version >SMC_V1 && first_contact) { - vec[i].iov_base = &fce; + vec[i].iov_base = &fce_v2x; vec[i++].iov_len = fce_len;if (!conn->lgr->is_smcd) {if (clc->hdr.type ==SMC_CLC_CONFIRM ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 35/356 net/smc: introduce sub-functions for smc_clc_send_confirm_accept()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 5205ac4483b630e47c65f192a3ac19be7a8ea648 ]
There is a large if-else block in smc_clc_send_confirm_accept() and it is better to split it into two sub-functions.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/smc_clc.c | 197 +++++++++++++++++++++++++++------------------- 1 file changed, 115 insertions(+), 82 deletions(-)
net/smc/smc_clc.c +115 -82
@@ -1007,6 +1007,112 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)return reason_code; } +static void +smcd_clc_prep_confirm_accept (struct smc_connection *conn, +struct smc_clc_msg_accept_confirm_v2 *clc_v2, +int first_contact,u8 version, +u8 *eid,struct smc_init_info *ini, +int *fce_len, +struct smc_clc_first_contact_ext_v2x *fce_v2x, +struct smc_clc_msg_trail *trl) +{ +struct smcd_dev *smcd = conn->lgr->smcd; +struct smc_clc_msg_accept_confirm *clc; +int len; + +/* SMC-D specific settings */ + clc = (struct smc_clc_msg_accept_confirm *)clc_v2; +memcpy (clc->hdr.eyecatcher,SMCD_EYECATCHER , +sizeof (SMCD_EYECATCHER )); + clc->hdr.typev1 =SMC_TYPE_D ; + clc->d0.gid =htonll (smcd->ops->get_local_gid (smcd)); + clc->d0.token =htonll (conn->rmb_desc->token); + clc->d0.dmbe_size = conn->rmbe_size_comp; + clc->d0.dmbe_idx =0 ; +memcpy (&clc->d0.linkid, conn->lgr->id,SMC_LGR_ID_SIZE ); +if (version ==SMC_V1 ) { + clc->hdr.length =htons (SMCD_CLC_ACCEPT_CONFIRM_LEN ); + }else { + clc_v2->d1.chid =htons (smc_ism_get_chid (smcd)); +if (eid && eid[0 ]) +memcpy (clc_v2->d1.eid, eid,SMC_MAX_EID_LEN ); + len =SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 ; +if (first_contact) { + *fce_len =smc_clc_fill_fce_v2x (fce_v2x, ini); + len += *fce_len; + } + clc_v2->hdr.length =htons (len); + } +memcpy (trl->eyecatcher,SMCD_EYECATCHER , +sizeof (SMCD_EYECATCHER )); +} + +static void +smcr_clc_prep_confirm_accept (struct smc_connection *conn, +struct smc_clc_msg_accept_confirm_v2 *clc_v2, +int first_contact,u8 version, +u8 *eid,struct smc_init_info *ini, +int *fce_len, +struct smc_clc_first_contact_ext_v2x *fce_v2x, +struct smc_clc_fce_gid_ext *gle, +struct smc_clc_msg_trail *trl) +{ +struct smc_clc_msg_accept_confirm *clc; +struct smc_link *link = conn->lnk; +int len; + +/* SMC-R specific settings */ + clc = (struct smc_clc_msg_accept_confirm *)clc_v2; +memcpy (clc->hdr.eyecatcher,SMC_EYECATCHER , +sizeof (SMC_EYECATCHER )); + clc->hdr.typev1 =SMC_TYPE_R ; +memcpy (clc->r0.lcl.id_for_peer, local_systemid, +sizeof (local_systemid)); +memcpy (&clc->r0.lcl.gid, link->gid,SMC_GID_SIZE ); +memcpy (&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport -1 ], +ETH_ALEN ); +hton24 (clc->r0.qpn, link->roce_qp->qp_num); + clc->r0.rmb_rkey = +htonl (conn->rmb_desc->mr[link->link_idx]->rkey); + clc->r0.rmbe_idx =1 ;/* for now: 1 RMB = 1 RMBE */ + clc->r0.rmbe_alert_token =htonl (conn->alert_token_local); +switch (clc->hdr.type) { +case SMC_CLC_ACCEPT : + clc->r0.qp_mtu = link->path_mtu; +break ; +case SMC_CLC_CONFIRM : + clc->r0.qp_mtu =min (link->path_mtu, link->peer_mtu); +break ; + } + clc->r0.rmbe_size = conn->rmbe_size_comp; + clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ? +cpu_to_be64 ((uintptr_t )conn->rmb_desc->cpu_addr) : +cpu_to_be64 ((u64 )sg_dma_address + (conn->rmb_desc->sgt[link->link_idx].sgl)); +hton24 (clc->r0.psn, link->psn_initial); +if (version ==SMC_V1 ) { + clc->hdr.length =htons (SMCR_CLC_ACCEPT_CONFIRM_LEN ); + }else { +if (eid && eid[0 ]) +memcpy (clc_v2->r1.eid, eid,SMC_MAX_EID_LEN ); + len =SMCR_CLC_ACCEPT_CONFIRM_LEN_V2 ; +if (first_contact) { + *fce_len =smc_clc_fill_fce_v2x (fce_v2x, ini); + len += *fce_len; + fce_v2x->fce_v2_base.v2_direct = + !link->lgr->uses_gateway; +if (clc->hdr.type ==SMC_CLC_CONFIRM ) { +memset (gle,0 ,sizeof (*gle)); + gle->gid_cnt = ini->smcrv2.gidlist.len; + len +=sizeof (*gle); + len += gle->gid_cnt *sizeof (gle->gid[0 ]); + } + } + clc_v2->hdr.length =htons (len); + } +memcpy (trl->eyecatcher,SMC_EYECATCHER ,sizeof (SMC_EYECATCHER )); +} +/* build and send CLC CONFIRM / ACCEPT message */ static int smc_clc_send_confirm_accept(struct smc_sock *smc, struct smc_clc_msg_accept_confirm_v2 *clc_v2,
@@ -1015,11 +1121,10 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, {struct smc_clc_first_contact_ext_v2x fce_v2x;struct smc_connection *conn = &smc->conn; -struct smcd_dev *smcd = conn->lgr->smcd;struct smc_clc_msg_accept_confirm *clc;struct smc_clc_fce_gid_ext gle;struct smc_clc_msg_trail trl; -int i, len, fce_len; +int i, fce_len;struct kvec vec[5 ];struct msghdr msg;
@@ -1028,86 +1133,14 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc, clc->hdr.version = version;/* SMC version */ if (first_contact) clc->hdr.typev2 |=SMC_FIRST_CONTACT_MASK ; -if (conn->lgr->is_smcd) { -/* SMC-D specific settings */ -memcpy (clc->hdr.eyecatcher,SMCD_EYECATCHER , -sizeof (SMCD_EYECATCHER )); - clc->hdr.typev1 =SMC_TYPE_D ; - clc->d0.gid =htonll (smcd->ops->get_local_gid (smcd)); - clc->d0.token =htonll (conn->rmb_desc->token); - clc->d0.dmbe_size = conn->rmbe_size_comp; - clc->d0.dmbe_idx =0 ; -memcpy (&clc->d0.linkid, conn->lgr->id,SMC_LGR_ID_SIZE ); -if (version ==SMC_V1 ) { - clc->hdr.length =htons (SMCD_CLC_ACCEPT_CONFIRM_LEN ); - }else { - clc_v2->d1.chid =htons (smc_ism_get_chid (smcd)); -if (eid && eid[0 ]) -memcpy (clc_v2->d1.eid, eid,SMC_MAX_EID_LEN ); - len =SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 ; -if (first_contact) { - fce_len =smc_clc_fill_fce_v2x (&fce_v2x, ini); - len += fce_len; - } - clc_v2->hdr.length =htons (len); - } -memcpy (trl.eyecatcher,SMCD_EYECATCHER , -sizeof (SMCD_EYECATCHER )); - }else { -struct smc_link *link = conn->lnk; - -/* SMC-R specific settings */ -memcpy (clc->hdr.eyecatcher,SMC_EYECATCHER , -sizeof (SMC_EYECATCHER )); - clc->hdr.typev1 =SMC_TYPE_R ; - clc->hdr.length =htons (SMCR_CLC_ACCEPT_CONFIRM_LEN ); -memcpy (clc->r0.lcl.id_for_peer, local_systemid, -sizeof (local_systemid)); -memcpy (&clc->r0.lcl.gid, link->gid,SMC_GID_SIZE ); -memcpy (&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport -1 ], -ETH_ALEN ); -hton24 (clc->r0.qpn, link->roce_qp->qp_num); - clc->r0.rmb_rkey = -htonl (conn->rmb_desc->mr[link->link_idx]->rkey); - clc->r0.rmbe_idx =1 ;/* for now: 1 RMB = 1 RMBE */ - clc->r0.rmbe_alert_token =htonl (conn->alert_token_local); -switch (clc->hdr.type) { -case SMC_CLC_ACCEPT : - clc->r0.qp_mtu = link->path_mtu; -break ; -case SMC_CLC_CONFIRM : - clc->r0.qp_mtu =min (link->path_mtu, link->peer_mtu); -break ; - } - clc->r0.rmbe_size = conn->rmbe_size_comp; - clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ? -cpu_to_be64 ((uintptr_t )conn->rmb_desc->cpu_addr) : -cpu_to_be64 ((u64 )sg_dma_address - (conn->rmb_desc->sgt[link->link_idx].sgl)); -hton24 (clc->r0.psn, link->psn_initial); -if (version ==SMC_V1 ) { - clc->hdr.length =htons (SMCR_CLC_ACCEPT_CONFIRM_LEN ); - }else { -if (eid && eid[0 ]) -memcpy (clc_v2->r1.eid, eid,SMC_MAX_EID_LEN ); - len =SMCR_CLC_ACCEPT_CONFIRM_LEN_V2 ; -if (first_contact) { - fce_len =smc_clc_fill_fce_v2x (&fce_v2x, ini); - len += fce_len; - fce_v2x.fce_v2_base.v2_direct = - !link->lgr->uses_gateway; -if (clc->hdr.type ==SMC_CLC_CONFIRM ) { -memset (&gle,0 ,sizeof (gle)); - gle.gid_cnt = ini->smcrv2.gidlist.len; - len +=sizeof (gle); - len += gle.gid_cnt *sizeof (gle.gid[0 ]); - } - } - clc_v2->hdr.length =htons (len); - } -memcpy (trl.eyecatcher,SMC_EYECATCHER ,sizeof (SMC_EYECATCHER )); - } - +if (conn->lgr->is_smcd) +smcd_clc_prep_confirm_accept (conn, clc_v2, first_contact, + version, eid, ini, &fce_len, + &fce_v2x, &trl); +else +smcr_clc_prep_confirm_accept (conn, clc_v2, first_contact, + version, eid, ini, &fce_len, + &fce_v2x, &gle, &trl);memset (&msg,0 ,sizeof (msg)); i =0 ; vec[i].iov_base = clc_v2;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 36/356 net/smc: unify the structs of accept or confirm message for v1 and v2
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 9505450d55b0f7809fe63c36ad9339a909461c87 ]
The structs of CLC accept and confirm messages for SMCv1 and SMCv2 are separately defined and often casted to each other in the code, which may increase the risk of errors caused by future divergence of them. So unify them into one struct for better maintainability.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/af_smc.c | 52 +++++++++++++------------------------ net/smc/smc_clc.c | 65 ++++++++++++++++++++--------------------------- net/smc/smc_clc.h | 42 +++++++++++++----------------- 3 files changed, 62 insertions(+), 97 deletions(-)
net/smc/af_smc.c +17 -35
@@ -659,8 +659,6 @@ static bool smc_isascii(char *hostname)static void smc_conn_save_peer_info_fce (struct smc_sock *smc,struct smc_clc_msg_accept_confirm *clc) { -struct smc_clc_msg_accept_confirm_v2 *clc_v2 = - (struct smc_clc_msg_accept_confirm_v2 *)clc;struct smc_clc_first_contact_ext *fce;int clc_v2_len;
@@ -669,17 +667,15 @@ static void smc_conn_save_peer_info_fce(struct smc_sock *smc,return ;if (smc->conn.lgr->is_smcd) { -memcpy (smc->conn.lgr->negotiated_eid, clc_v2->d1.eid, +memcpy (smc->conn.lgr->negotiated_eid, clc->d1.eid,SMC_MAX_EID_LEN ); - clc_v2_len = offsetofend(struct smc_clc_msg_accept_confirm_v2, - d1); + clc_v2_len = offsetofend(struct smc_clc_msg_accept_confirm, d1); }else { -memcpy (smc->conn.lgr->negotiated_eid, clc_v2->r1.eid, +memcpy (smc->conn.lgr->negotiated_eid, clc->r1.eid,SMC_MAX_EID_LEN ); - clc_v2_len = offsetofend(struct smc_clc_msg_accept_confirm_v2, - r1); + clc_v2_len = offsetofend(struct smc_clc_msg_accept_confirm, r1); } - fce = (struct smc_clc_first_contact_ext *)(((u8 *)clc_v2) + clc_v2_len); + fce = (struct smc_clc_first_contact_ext *)(((u8 *)clc) + clc_v2_len); smc->conn.lgr->peer_os = fce->os_type; smc->conn.lgr->peer_smc_release = fce->release;if (smc_isascii (fce->hostname))
@@ -1131,13 +1127,13 @@ static int smc_connect_ism_vlan_cleanup(struct smc_sock *smc, }#define SMC_CLC_MAX_ACCEPT_LEN \ - (sizeof(struct smc_clc_msg_accept_confirm_v2) + \ + (sizeof(struct smc_clc_msg_accept_confirm) + \ sizeof(struct smc_clc_first_contact_ext_v2x) + \ sizeof(struct smc_clc_msg_trail))/* CLC handshake during connect */ static int smc_connect_clc (struct smc_sock *smc, -struct smc_clc_msg_accept_confirm_v2 *aclc2, +struct smc_clc_msg_accept_confirm *aclc,struct smc_init_info *ini) {int rc =0 ;
@@ -1147,7 +1143,7 @@ static int smc_connect_clc(struct smc_sock *smc,if (rc)return rc;/* receive SMC Accept CLC message */ -return smc_clc_wait_msg (smc, aclc2,SMC_CLC_MAX_ACCEPT_LEN , +return smc_clc_wait_msg (smc, aclc,SMC_CLC_MAX_ACCEPT_LEN ,SMC_CLC_ACCEPT ,CLC_WAIT_TIME ); }
@@ -1183,10 +1179,8 @@ static int smc_connect_rdma_v2_prepare(struct smc_sock *smc,struct smc_clc_msg_accept_confirm *aclc, struct smc_init_info *ini) { - struct smc_clc_msg_accept_confirm_v2 *clc_v2 = - (struct smc_clc_msg_accept_confirm_v2 *)aclc; struct smc_clc_first_contact_ext *fce = -smc_get_clc_first_contact_ext (clc_v2, false); +smc_get_clc_first_contact_ext (aclc, false);struct net *net =sock_net (&smc->sk);int rc;
@@ -1309,10 +1303,7 @@ static int smc_connect_rdma(struct smc_sock *smc, }if (aclc->hdr.version >SMC_V1 ) { -struct smc_clc_msg_accept_confirm_v2 *clc_v2 = - (struct smc_clc_msg_accept_confirm_v2 *)aclc; - - eid = clc_v2->r1.eid; + eid = aclc->r1.eid;if (ini->first_contact_local)smc_fill_gid_list (link->lgr, &ini->smcrv2.gidlist, link->smcibdev, link->gid);
@@ -1353,7 +1344,7 @@ static int smc_connect_rdma(struct smc_sock *smc,* Determine from the CHID of the received CLC ACCEPT the ISM device chosen. */ static int -smc_v2_determine_accepted_chid (struct smc_clc_msg_accept_confirm_v2 *aclc, +smc_v2_determine_accepted_chid (struct smc_clc_msg_accept_confirm *aclc,struct smc_init_info *ini) {int i;
@@ -1380,12 +1371,9 @@ static int smc_connect_ism(struct smc_sock *smc, ini->first_contact_peer = aclc->hdr.typev2 &SMC_FIRST_CONTACT_MASK ;if (aclc->hdr.version ==SMC_V2 ) { -struct smc_clc_msg_accept_confirm_v2 *aclc_v2 = - (struct smc_clc_msg_accept_confirm_v2 *)aclc; -if (ini->first_contact_peer) {struct smc_clc_first_contact_ext *fce = -smc_get_clc_first_contact_ext (aclc_v2, true); +smc_get_clc_first_contact_ext (aclc, true); ini->release_nr = fce->release; rc =smc_clc_clnt_v2x_features_validate (fce, ini);
@@ -1393,7 +1381,7 @@ static int smc_connect_ism(struct smc_sock *smc,return rc; } - rc =smc_v2_determine_accepted_chid (aclc_v2, ini); + rc =smc_v2_determine_accepted_chid (aclc, ini);if (rc)return rc; }
@@ -1419,12 +1407,8 @@ static int smc_connect_ism(struct smc_sock *smc,smc_rx_init (smc);smc_tx_init (smc); -if (aclc->hdr.version >SMC_V1 ) { -struct smc_clc_msg_accept_confirm_v2 *clc_v2 = - (struct smc_clc_msg_accept_confirm_v2 *)aclc; - - eid = clc_v2->d1.eid; - } +if (aclc->hdr.version >SMC_V1 ) + eid = aclc->d1.eid; rc =smc_clc_send_confirm (smc, ini->first_contact_local, aclc->hdr.version, eid, ini);
@@ -1475,7 +1459,6 @@ static int smc_connect_check_aclc(struct smc_init_info *ini,static int __smc_connect (struct smc_sock *smc) {u8 version =smc_ism_is_v2_capable () ?SMC_V2 :SMC_V1 ; -struct smc_clc_msg_accept_confirm_v2 *aclc2;struct smc_clc_msg_accept_confirm *aclc;struct smc_init_info *ini =NULL ;u8 *buf =NULL ;
@@ -1523,11 +1506,10 @@ static int __smc_connect(struct smc_sock *smc) rc =SMC_CLC_DECL_MEM ; goto fallback; } - aclc2 = (struct smc_clc_msg_accept_confirm_v2 *)buf; - aclc = (struct smc_clc_msg_accept_confirm *)aclc2; + aclc = (struct smc_clc_msg_accept_confirm *)buf;/* perform CLC handshake */ - rc =smc_connect_clc (smc, aclc2, ini); + rc =smc_connect_clc (smc, aclc, ini);if (rc) {/* -EAGAIN on timeout, see tcp_recvmsg() */ if (rc == -EAGAIN ) {
net/smc/smc_clc.c +28 -37
196 lines not on this page · raw message
net/smc/smc_clc.h +17 -25
71 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 37/356 net/smc: define a reserved CHID range for virtual ISM devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 8dd512df3c98ce8081e3541990bf849157675723 ]
According to virtual ISM support feature defined by SMCv2.1, CHIDs in the range 0xFF00 to 0xFFFF are reserved for use by virtual ISM devices.
And two helpers are introduced to distinguish virtual ISM devices from the existing platform firmware ISM devices.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/smc_ism.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
net/smc/smc_ism.h +20 -0
@@ -15,6 +15,8 @@#include "smc.h" +#define SMC_VIRTUAL_ISM_CHID_MASK 0xFF00 +struct smcd_dev_list {/* List of SMCD devices */ struct list_head list;struct mutex mutex;/* Protects list of devices */
@@ -56,4 +58,22 @@ static inline int smc_ism_write(struct smcd_dev *smcd, u64 dmb_tok, return rc < 0 ? rc : 0; } +static inline bool __smc_ism_is_virtual (u16 chid) +{ +/* CHIDs in range of 0xFF00 to 0xFFFF are reserved +* for virtual ISM device. +* +* loopback-ism: 0xFFFF +* virtio-ism: 0xFF00 ~ 0xFFFE +*/ +return ((chid &0xFF00 ) ==0xFF00 ); +} + +static inline bool smc_ism_is_virtual (struct smcd_dev *smcd) +{ +u16 chid = smcd->ops->get_chid (smcd); + +return __smc_ism_is_virtual (chid); +} +#endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 38/356 net/smc: compatible with 128-bits extended GID of virtual ISM device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit b40584d145700addc70cc29e4f0850a4ed955b1c ]
According to virtual ISM support feature defined by SMCv2.1, GIDs of virtual ISM device are UUIDs defined by RFC4122, which are 128-bits long. So some adaptation work is required. And note that the GIDs of existing platform firmware ISM devices still remain 64-bits long.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- drivers/s390/net/ism_drv.c | 19 ++++++----- include/net/smc.h | 15 ++++++--- net/smc/af_smc.c | 66 ++++++++++++++++++++++++++++++-------- net/smc/smc.h | 3 -- net/smc/smc_clc.c | 43 ++++++++++++++++++------- net/smc/smc_clc.h | 10 ++++-- net/smc/smc_core.c | 31 ++++++++++++------ net/smc/smc_core.h | 17 +++++++--- net/smc/smc_diag.c | 7 ++-- net/smc/smc_ism.c | 17 ++++++---- net/smc/smc_ism.h | 3 +- net/smc/smc_pnet.c | 4 +-- 12 files changed, 167 insertions(+), 68 deletions(-)
drivers/s390/net/ism_drv.c +11 -8
@@ -762,10 +762,10 @@ static int ism_query_rgid(struct ism_dev *ism, u64 rgid, u32 vid_valid,return ism_cmd (ism, &cmd); } -static int smcd_query_rgid (struct smcd_dev *smcd,u64 rgid,u32 vid_valid, -u32 vid) +static int smcd_query_rgid (struct smcd_dev *smcd,struct smcd_gid *rgid, +u32 vid_valid,u32 vid) { -return ism_query_rgid (smcd->priv, rgid, vid_valid, vid); +return ism_query_rgid (smcd->priv, rgid->gid, vid_valid, vid); } static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
@@ -816,10 +816,11 @@ static int ism_signal_ieq(struct ism_dev *ism, u64 rgid, u32 trigger_irq,return ism_cmd (ism, &cmd); } -static int smcd_signal_ieq (struct smcd_dev *smcd,u64 rgid,u32 trigger_irq, -u32 event_code,u64 info) +static int smcd_signal_ieq (struct smcd_dev *smcd,struct smcd_gid *rgid, +u32 trigger_irq,u32 event_code,u64 info) { -return ism_signal_ieq (smcd->priv, rgid, trigger_irq, event_code, info); +return ism_signal_ieq (smcd->priv, rgid->gid, + trigger_irq, event_code, info); } static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
@@ -840,9 +841,11 @@ static u64 ism_get_local_gid(struct ism_dev *ism)return ism->local_gid; } -static u64 smcd_get_local_gid (struct smcd_dev *smcd) +static void smcd_get_local_gid (struct smcd_dev *smcd, +struct smcd_gid *smcd_gid) { -return ism_get_local_gid (smcd->priv); + smcd_gid->gid =ism_get_local_gid (smcd->priv); + smcd_gid->gid_ext =0 ; }static u16 ism_get_chid (struct ism_dev *ism)
include/net/smc.h +10 -5
@@ -52,9 +52,14 @@ struct smcd_dmb {struct smcd_dev ;struct ism_client ; +struct smcd_gid { +u64 gid; +u64 gid_ext; +}; +struct smcd_ops { -int (*query_remote_gid)(struct smcd_dev *dev,u64 rgid,u32 vid_valid, -u32 vid); +int (*query_remote_gid)(struct smcd_dev *dev,struct smcd_gid *rgid, +u32 vid_valid,u32 vid);int (*register_dmb)(struct smcd_dev *dev,struct smcd_dmb *dmb,struct ism_client *client);int (*unregister_dmb)(struct smcd_dev *dev,struct smcd_dmb *dmb);
@@ -62,14 +67,14 @@ struct smcd_ops {int (*del_vlan_id)(struct smcd_dev *dev,u64 vlan_id);int (*set_vlan_required)(struct smcd_dev *dev);int (*reset_vlan_required)(struct smcd_dev *dev); -int (*signal_event)(struct smcd_dev *dev,u64 rgid,u32 trigger_irq, -u32 event_code,u64 info); +int (*signal_event)(struct smcd_dev *dev,struct smcd_gid *rgid, +u32 trigger_irq,u32 event_code,u64 info);int (*move_data)(struct smcd_dev *dev,u64 dmb_tok,unsigned int idx,bool sf,unsigned int offset,void *data,unsigned int size);int (*supports_v2)(void ); u8* (*get_system_eid)(void); -u64 (*get_local_gid)(struct smcd_dev *dev); +void (*get_local_gid)(struct smcd_dev *dev,struct smcd_gid *gid);u16 (*get_chid)(struct smcd_dev *dev);struct device * (*get_dev)(struct smcd_dev *dev); };
net/smc/af_smc.c +53 -13
130 lines not on this page · raw message
net/smc/smc.h +0 -3
@@ -29,9 +29,6 @@#define SMCPROTO_SMC 0/* SMC protocol, IPv4 */ #define SMCPROTO_SMC6 1/* SMC protocol, IPv6 */ -#define SMC_MAX_ISM_DEVS 8/* max # of proposed non-native ISM -* devices -*/ #define SMC_AUTOCORKING_DEFAULT_SIZE 0x10000/* 64K by default */ extern struct proto smc_proto;
net/smc/smc_clc.c +32 -11
96 lines not on this page · raw message
net/smc/smc_clc.h +8 -2
@@ -171,6 +171,11 @@ struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */#define SMC_CLC_MAX_V6_PREFIX 8#define SMC_CLC_MAX_UEID 8 +#define SMCD_CLC_MAX_V2_GID_ENTRIES 8/* max # of CHID-GID entries in CLC +* proposal SMC-Dv2 extension. +* each ISM device takes one entry and +* each virtual ISM takes two entries. +*/ struct smc_clc_msg_proposal_area {struct smc_clc_msg_proposal pclc_base;
@@ -180,7 +185,8 @@ struct smc_clc_msg_proposal_area {struct smc_clc_v2_extension pclc_v2_ext;u8 user_eids[SMC_CLC_MAX_UEID ][SMC_MAX_EID_LEN ];struct smc_clc_smcd_v2_extension pclc_smcd_v2_ext; -struct smc_clc_smcd_gid_chid pclc_gidchids[SMC_MAX_ISM_DEVS ]; +struct smc_clc_smcd_gid_chid + pclc_gidchids[SMCD_CLC_MAX_V2_GID_ENTRIES ];struct smc_clc_msg_trail pclc_trl; };
@@ -271,7 +277,7 @@ struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */struct {/* v2 only, but 12 bytes reserved in v1 */ __be16 chid;u8 eid[SMC_MAX_EID_LEN ]; -u8 reserved5[8 ]; +__be64 gid_ext; } __packed d1; }; };
net/smc/smc_core.c +21 -10
@@ -506,6 +506,7 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr, {char smc_pnet[SMC_MAX_PNETID_LEN +1 ];struct smcd_dev *smcd = lgr->smcd; +struct smcd_gid smcd_gid;struct nlattr *attrs;void *nlh;
@@ -521,11 +522,11 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,if (nla_put_u32 (skb,SMC_NLA_LGR_D_ID , *((u32 *)&lgr->id))) goto errattr; + smcd->ops->get_local_gid (smcd, &smcd_gid);if (nla_put_u64_64bit (skb,SMC_NLA_LGR_D_GID , - smcd->ops->get_local_gid (smcd), -SMC_NLA_LGR_D_PAD )) + smcd_gid.gid,SMC_NLA_LGR_D_PAD )) goto errattr; -if (nla_put_u64_64bit (skb,SMC_NLA_LGR_D_PEER_GID , lgr->peer_gid, +if (nla_put_u64_64bit (skb,SMC_NLA_LGR_D_PEER_GID , lgr->peer_gid.gid,SMC_NLA_LGR_D_PAD )) goto errattr;if (nla_put_u8 (skb,SMC_NLA_LGR_D_VLAN_ID , lgr->vlan_id))
@@ -876,7 +877,10 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)/* SMC-D specific settings */ smcd = ini->ism_dev[ini->ism_selected];get_device (smcd->ops->get_dev (smcd)); - lgr->peer_gid = ini->ism_peer_gid[ini->ism_selected]; + lgr->peer_gid.gid = + ini->ism_peer_gid[ini->ism_selected].gid; + lgr->peer_gid.gid_ext = + ini->ism_peer_gid[ini->ism_selected].gid_ext; lgr->smcd = ini->ism_dev[ini->ism_selected]; lgr_list = &ini->ism_dev[ini->ism_selected]->lgr_list; lgr_lock = &lgr->smcd->lgr_lock;
@@ -1514,7 +1518,8 @@ void smc_lgr_terminate_sched(struct smc_link_group *lgr) }/* Called when peer lgr shutdown (regularly or abnormally) is received */ -void smc_smcd_terminate (struct smcd_dev *dev,u64 peer_gid,unsigned short vlan) +void smc_smcd_terminate (struct smcd_dev *dev,struct smcd_gid *peer_gid, +unsigned short vlan) {struct smc_link_group *lgr, *l;LIST_HEAD (lgr_free_list);
@@ -1522,9 +1527,12 @@ void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, unsigned short vlan)/* run common cleanup function and build free list */ spin_lock_bh (&dev->lgr_lock);list_for_each_entry_safe (lgr, l, &dev->lgr_list, list) { -if ((!peer_gid || lgr->peer_gid == peer_gid) && +if ((!peer_gid->gid || + (lgr->peer_gid.gid == peer_gid->gid && + !smc_ism_is_virtual (dev) ?1 : + lgr->peer_gid.gid_ext == peer_gid->gid_ext)) && (vlan ==VLAN_VID_MASK || lgr->vlan_id == vlan)) { -if (peer_gid)/* peer triggered termination */ +if (peer_gid->gid)/* peer triggered termination */ lgr->peer_shutdown =1 ;list_move (&lgr->list, &lgr_free_list); lgr->freeing =1 ;
@@ -1860,9 +1868,12 @@ static bool smcr_lgr_match(struct smc_link_group *lgr, u8 smcr_version, }static bool smcd_lgr_match (struct smc_link_group *lgr, -struct smcd_dev *smcismdev,u64 peer_gid) +struct smcd_dev *smcismdev, +struct smcd_gid *peer_gid) { -return lgr->peer_gid == peer_gid && lgr->smcd == smcismdev; +return lgr->peer_gid.gid == peer_gid->gid && lgr->smcd == smcismdev && +smc_ism_is_virtual (smcismdev) ? + (lgr->peer_gid.gid_ext == peer_gid->gid_ext) :1 ; }/* create a new SMC connection (and a new link group if necessary) */
@@ -1892,7 +1903,7 @@ int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini)write_lock_bh (&lgr->conns_lock); if ((ini->is_smcd ? smcd_lgr_match(lgr, ini->ism_dev[ini->ism_selected], - ini->ism_peer_gid[ini->ism_selected]) : + &ini->ism_peer_gid[ini->ism_selected]) : smcr_lgr_match(lgr, ini->smcr_version, ini->peer_systemid, ini->peer_gid, ini->peer_mac, role,
net/smc/smc_core.h +12 -5
@@ -17,9 +17,11 @@#include <linux/pci.h> #include <rdma/ib_verbs.h> #include <net/genetlink.h> +#include <net/smc.h> #include "smc.h" #include "smc_ib.h" +#include "smc_clc.h" #define SMC_RMBS_PER_LGR_MAX 255/* max. # of RMBs per link group */ #define SMC_CONN_PER_LGR_MIN 16/* min. # of connections per link group */
@@ -355,7 +357,7 @@ struct smc_link_group {/* max links can be added in lgr */ };struct {/* SMC-D */ -u64 peer_gid; +struct smcd_gid peer_gid;/* Peer GID (remote) */ struct smcd_dev *smcd;/* ISM device for VLAN reg. */
@@ -392,6 +394,11 @@ struct smc_init_info_smcrv2 {struct smc_gidlist gidlist; }; +#define SMC_MAX_V2_ISM_DEVS SMCD_CLC_MAX_V2_GID_ENTRIES +/* max # of proposed non-native ISM devices, +* which can't exceed the max # of CHID-GID +* entries in CLC proposal SMC-Dv2 extension. +*/ struct smc_init_info {u8 is_smcd;u8 smc_type_v1;
@@ -416,9 +423,9 @@ struct smc_init_info {u32 ib_clcqpn;struct smc_init_info_smcrv2 smcrv2;/* SMC-D */ -u64 ism_peer_gid[SMC_MAX_ISM_DEVS +1 ]; -struct smcd_dev *ism_dev[SMC_MAX_ISM_DEVS +1 ]; -u16 ism_chid[SMC_MAX_ISM_DEVS +1 ]; +struct smcd_gid ism_peer_gid[SMC_MAX_V2_ISM_DEVS +1 ]; +struct smcd_dev *ism_dev[SMC_MAX_V2_ISM_DEVS +1 ]; +u16 ism_chid[SMC_MAX_V2_ISM_DEVS +1 ];u8 ism_offered_cnt;/* # of ISM devices offered */ u8 ism_selected;/* index of selected ISM dev*/ u8 smcd_version;
@@ -544,7 +551,7 @@ void smc_lgr_hold(struct smc_link_group *lgr);void smc_lgr_put (struct smc_link_group *lgr);void smcr_port_add (struct smc_ib_device *smcibdev,u8 ibport);void smcr_port_err (struct smc_ib_device *smcibdev,u8 ibport); -void smc_smcd_terminate (struct smcd_dev *dev,u64 peer_gid, +void smc_smcd_terminate (struct smcd_dev *dev,struct smcd_gid *peer_gid,unsigned short vlan);void smc_smcd_terminate_all (struct smcd_dev *dev);void smc_smcr_terminate_all (struct smc_ib_device *smcibdev);
net/smc/smc_diag.c +5 -2
@@ -21,6 +21,7 @@#include "smc.h" #include "smc_core.h" +#include "smc_ism.h" struct smc_diag_dump_ctx {int pos[2 ];
@@ -167,12 +168,14 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,struct smc_connection *conn = &smc->conn;struct smcd_diag_dmbinfo dinfo;struct smcd_dev *smcd = conn->lgr->smcd; +struct smcd_gid smcd_gid;memset (&dinfo,0 ,sizeof (dinfo)); dinfo.linkid = *((u32 *)conn->lgr->id); - dinfo.peer_gid = conn->lgr->peer_gid; - dinfo.my_gid = smcd->ops->get_local_gid (smcd); + dinfo.peer_gid = conn->lgr->peer_gid.gid; + smcd->ops->get_local_gid (smcd, &smcd_gid); + dinfo.my_gid = smcd_gid.gid; dinfo.token = conn->rmb_desc->token; dinfo.peer_token = conn->peer_token;
net/smc/smc_ism.c +11 -6
@@ -44,7 +44,8 @@ static struct ism_client smc_ism_client = {#endif /* Test if an ISM communication is possible - same CPC */ -int smc_ism_cantalk (u64 peer_gid,unsigned short vlan_id,struct smcd_dev *smcd) +int smc_ism_cantalk (struct smcd_gid *peer_gid,unsigned short vlan_id, +struct smcd_dev *smcd) {return smcd->ops->query_remote_gid (smcd, peer_gid, vlan_id ?1 :0 , vlan_id);
@@ -208,7 +209,7 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int dmb_len, dmb.dmb_len = dmb_len; dmb.sba_idx = dmb_desc->sba_idx; dmb.vlan_id = lgr->vlan_id; - dmb.rgid = lgr->peer_gid; + dmb.rgid = lgr->peer_gid.gid; rc = lgr->smcd->ops->register_dmb (lgr->smcd, &dmb, &smc_ism_client);if (!rc) { dmb_desc->sba_idx = dmb.sba_idx;
@@ -340,18 +341,20 @@ union smcd_sw_event_info {static void smcd_handle_sw_event (struct smc_ism_event_work *wrk) { +struct smcd_gid peer_gid = { .gid = wrk->event.tok, + .gid_ext =0 };union smcd_sw_event_info ev_info; ev_info.info = wrk->event.info;switch (wrk->event.code) {case ISM_EVENT_CODE_SHUTDOWN :/* Peer shut down DMBs */ -smc_smcd_terminate (wrk->smcd, wrk->event.tok, ev_info.vlan_id); +smc_smcd_terminate (wrk->smcd, &peer_gid, ev_info.vlan_id);break ;case ISM_EVENT_CODE_TESTLINK :/* Activity timer */ if (ev_info.code ==ISM_EVENT_REQUEST ) { ev_info.code =ISM_EVENT_RESPONSE ; wrk->smcd->ops->signal_event (wrk->smcd, - wrk->event.tok, + &peer_gid,ISM_EVENT_REQUEST_IR ,ISM_EVENT_CODE_TESTLINK , ev_info.info);
@@ -365,10 +368,12 @@ static void smc_ism_event_work(struct work_struct *work) {struct smc_ism_event_work *wrk = container_of(work, struct smc_ism_event_work, work); +struct smcd_gid smcd_gid = { .gid = wrk->event.tok, + .gid_ext =0 };switch (wrk->event.type) {case ISM_EVENT_GID :/* GID event, token is peer GID */ -smc_smcd_terminate (wrk->smcd, wrk->event.tok,VLAN_VID_MASK ); +smc_smcd_terminate (wrk->smcd, &smcd_gid,VLAN_VID_MASK );break ;case ISM_EVENT_DMB :break ;
@@ -525,7 +530,7 @@ int smc_ism_signal_shutdown(struct smc_link_group *lgr)memcpy (ev_info.uid, lgr->id,SMC_LGR_ID_SIZE ); ev_info.vlan_id = lgr->vlan_id; ev_info.code =ISM_EVENT_REQUEST ; - rc = lgr->smcd->ops->signal_event (lgr->smcd, lgr->peer_gid, + rc = lgr->smcd->ops->signal_event (lgr->smcd, &lgr->peer_gid,ISM_EVENT_REQUEST_IR ,ISM_EVENT_CODE_SHUTDOWN , ev_info.info);
net/smc/smc_ism.h +2 -1
@@ -32,7 +32,8 @@ struct smc_ism_vlanid { /* VLAN id set on ISM device */struct smcd_dev ; -int smc_ism_cantalk (u64 peer_gid,unsigned short vlan_id,struct smcd_dev *dev); +int smc_ism_cantalk (struct smcd_gid *peer_gid,unsigned short vlan_id, +struct smcd_dev *dev);void smc_ism_set_conn (struct smc_connection *conn);void smc_ism_unset_conn (struct smc_connection *conn);int smc_ism_get_vlan (struct smcd_dev *dev,unsigned short vlan_id);
net/smc/smc_pnet.c +2 -2
@@ -1113,8 +1113,8 @@ static void smc_pnet_find_ism_by_pnetid(struct net_device *ndev,list_for_each_entry (ismdev, &smcd_dev_list.list, list) {if (smc_pnet_match (ismdev->pnetid, ndev_pnetid) && !ismdev->going_away && - (!ini->ism_peer_gid[0 ] || - !smc_ism_cantalk (ini->ism_peer_gid[0 ], ini->vlan_id, + (!ini->ism_peer_gid[0 ].gid || + !smc_ism_cantalk (&ini->ism_peer_gid[0 ], ini->vlan_id, ismdev))) { ini->ism_dev[0 ] = ismdev;break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 39/356 net/smc: mark optional smcd_ops and check for support when called
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit d1d8d0b6c7c68b0665456831fa779174ebd78f90 ]
Some operations are not supported by new introduced Emulated-ISM, so mark them as optional and check if the device supports them when called.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- include/net/smc.h | 14 ++++++++------ net/smc/smc_ism.c | 9 ++++++++- 2 files changed, 16 insertions(+), 7 deletions(-)
include/net/smc.h +8 -6
@@ -63,12 +63,6 @@ struct smcd_ops {int (*register_dmb)(struct smcd_dev *dev,struct smcd_dmb *dmb,struct ism_client *client);int (*unregister_dmb)(struct smcd_dev *dev,struct smcd_dmb *dmb); -int (*add_vlan_id)(struct smcd_dev *dev,u64 vlan_id); -int (*del_vlan_id)(struct smcd_dev *dev,u64 vlan_id); -int (*set_vlan_required)(struct smcd_dev *dev); -int (*reset_vlan_required)(struct smcd_dev *dev); -int (*signal_event)(struct smcd_dev *dev,struct smcd_gid *rgid, -u32 trigger_irq,u32 event_code,u64 info);int (*move_data)(struct smcd_dev *dev,u64 dmb_tok,unsigned int idx,bool sf,unsigned int offset,void *data,unsigned int size);
@@ -77,6 +71,14 @@ struct smcd_ops {void (*get_local_gid)(struct smcd_dev *dev,struct smcd_gid *gid);u16 (*get_chid)(struct smcd_dev *dev);struct device * (*get_dev)(struct smcd_dev *dev); + +/* optional operations */ +int (*add_vlan_id)(struct smcd_dev *dev,u64 vlan_id); +int (*del_vlan_id)(struct smcd_dev *dev,u64 vlan_id); +int (*set_vlan_required)(struct smcd_dev *dev); +int (*reset_vlan_required)(struct smcd_dev *dev); +int (*signal_event)(struct smcd_dev *dev,struct smcd_gid *rgid, +u32 trigger_irq,u32 event_code,u64 info); };struct smcd_dev {
net/smc/smc_ism.c +8 -1
@@ -105,6 +105,8 @@ int smc_ism_get_vlan(struct smcd_dev *smcd, unsigned short vlanid)if (!vlanid)/* No valid vlan id */ return -EINVAL ; +if (!smcd->ops->add_vlan_id) +return -EOPNOTSUPP ;/* create new vlan entry, in case we need it */ new_vlan =kzalloc (sizeof (*new_vlan),GFP_KERNEL );
@@ -150,6 +152,8 @@ int smc_ism_put_vlan(struct smcd_dev *smcd, unsigned short vlanid)if (!vlanid)/* No valid vlan id */ return -EINVAL ; +if (!smcd->ops->del_vlan_id) +return -EOPNOTSUPP ;spin_lock_irqsave (&smcd->lock, flags);list_for_each_entry (vlan, &smcd->vlan, list) {
@@ -351,7 +355,8 @@ static void smcd_handle_sw_event(struct smc_ism_event_work *wrk)smc_smcd_terminate (wrk->smcd, &peer_gid, ev_info.vlan_id);break ;case ISM_EVENT_CODE_TESTLINK :/* Activity timer */ -if (ev_info.code ==ISM_EVENT_REQUEST ) { +if (ev_info.code ==ISM_EVENT_REQUEST && + wrk->smcd->ops->signal_event) { ev_info.code =ISM_EVENT_RESPONSE ; wrk->smcd->ops->signal_event(wrk->smcd, &peer_gid,
@@ -526,6 +531,8 @@ int smc_ism_signal_shutdown(struct smc_link_group *lgr)if (lgr->peer_shutdown)return 0 ; +if (!lgr->smcd->ops->signal_event) +return 0 ;memcpy (ev_info.uid, lgr->id,SMC_LGR_ID_SIZE ); ev_info.vlan_id = lgr->vlan_id;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 40/356 net/smc: add operations to merge sndbuf with peer DMB
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 4398888268582cb51b69c6ee94f551bb8d37d12f ]
In some scenarios using Emulated-ISM device, sndbuf can share the same physical memory region with peer DMB to avoid data copy from one side to the other. In such case the sndbuf is only a descriptor that describes the shared memory and does not actually occupy memory, it's more like a ghost buffer.
+----------+ +----------+
| socket A | | socket B |
+----------+ +----------+
| |
+--------+ +--------+
| sndbuf | | DMB |
| desc | | desc |
+--------+ +--------+
| |
| +----v-----+
+--------------------------> memory |
+----------+So here introduces three new SMC-D device operations to check if this feature is supported by device, and to {attach|detach} ghost sndbuf to peer DMB. For now only loopback-ism supports this.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- include/net/smc.h | 3 +++ net/smc/smc_ism.c | 40 ++++++++++++++++++++++++++++++++++++++++ net/smc/smc_ism.h | 4 ++++ 3 files changed, 47 insertions(+)
include/net/smc.h +3 -0
@@ -79,6 +79,9 @@ struct smcd_ops {int (*reset_vlan_required)(struct smcd_dev *dev);int (*signal_event)(struct smcd_dev *dev,struct smcd_gid *rgid,u32 trigger_irq,u32 event_code,u64 info); +int (*support_dmb_nocopy)(struct smcd_dev *dev); +int (*attach_dmb)(struct smcd_dev *dev,struct smcd_dmb *dmb); +int (*detach_dmb)(struct smcd_dev *dev,u64 token); };struct smcd_dev {
net/smc/smc_ism.c +40 -0
@@ -228,6 +228,46 @@ int smc_ism_register_dmb(struct smc_link_group *lgr, int dmb_len,#endif } +bool smc_ism_support_dmb_nocopy (struct smcd_dev *smcd) +{ +/* for now only loopback-ism supports +* merging sndbuf with peer DMB to avoid +* data copies between them. +*/ +return (smcd->ops->support_dmb_nocopy && + smcd->ops->support_dmb_nocopy (smcd)); +} + +int smc_ism_attach_dmb (struct smcd_dev *dev,u64 token, +struct smc_buf_desc *dmb_desc) +{ +struct smcd_dmb dmb; +int rc =0 ; + +if (!dev->ops->attach_dmb) +return -EINVAL ; + +memset (&dmb,0 ,sizeof (dmb)); + dmb.dmb_tok = token; + rc = dev->ops->attach_dmb (dev, &dmb); +if (!rc) { + dmb_desc->sba_idx = dmb.sba_idx; + dmb_desc->token = dmb.dmb_tok; + dmb_desc->cpu_addr = dmb.cpu_addr; + dmb_desc->dma_addr = dmb.dma_addr; + dmb_desc->len = dmb.dmb_len; + } +return rc; +} + +int smc_ism_detach_dmb (struct smcd_dev *dev,u64 token) +{ +if (!dev->ops->detach_dmb) +return -EINVAL ; + +return dev->ops->detach_dmb (dev, token); +} +static int smc_nl_handle_smcd_dev (struct smcd_dev *smcd,struct sk_buff *skb,struct netlink_callback *cb)
net/smc/smc_ism.h +4 -0
@@ -41,6 +41,10 @@ int smc_ism_put_vlan(struct smcd_dev *dev, unsigned short vlan_id);int smc_ism_register_dmb (struct smc_link_group *lgr,int buf_size,struct smc_buf_desc *dmb_desc);int smc_ism_unregister_dmb (struct smcd_dev *dev,struct smc_buf_desc *dmb_desc); +bool smc_ism_support_dmb_nocopy (struct smcd_dev *smcd); +int smc_ism_attach_dmb (struct smcd_dev *dev,u64 token, +struct smc_buf_desc *dmb_desc); +int smc_ism_detach_dmb (struct smcd_dev *dev,u64 token);int smc_ism_signal_shutdown (struct smc_link_group *lgr);void smc_ism_get_system_eid (u8 **eid);u16 smc_ism_get_chid (struct smcd_dev *dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 41/356 net/smc: {at|de}tach sndbuf to peer DMB if supported
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit ae2be35cbed2c8385e890147ea321a3fcc3ca5fa ]
If the device used by SMC-D supports merging local sndbuf to peer DMB, then create sndbuf descriptor and attach it to peer DMB once peer token is obtained, and detach and free the sndbuf descriptor when the connection is freed.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/af_smc.c | 16 ++++++++++++ net/smc/smc_core.c | 61 +++++++++++++++++++++++++++++++++++++++++++++- net/smc/smc_core.h | 1 + 3 files changed, 77 insertions(+), 1 deletion(-)
net/smc/af_smc.c +16 -0
@@ -1418,6 +1418,14 @@ static int smc_connect_ism(struct smc_sock *smc, }smc_conn_save_peer_info (smc, aclc); + +if (smc_ism_support_dmb_nocopy (smc->conn.lgr->smcd)) { + rc =smcd_buf_attach (smc); +if (rc) { + rc =SMC_CLC_DECL_MEM ;/* try to fallback */ + goto connect_abort; + } + }smc_close_init (smc);smc_rx_init (smc);smc_tx_init (smc);
@@ -2522,6 +2530,14 @@ static void smc_listen_work(struct work_struct *work)mutex_unlock (&smc_server_lgr_pending); }smc_conn_save_peer_info (new_smc, cclc); + +if (ini->is_smcd && +smc_ism_support_dmb_nocopy (new_smc->conn.lgr->smcd)) { + rc =smcd_buf_attach (new_smc); +if (rc) + goto out_decl; + } +smc_listen_out_connected (new_smc);SMC_STAT_SERV_SUCC_INC (sock_net (newclcsock->sk), ini); goto out_free;
net/smc/smc_core.c +60 -1
96 lines not on this page · raw message
net/smc/smc_core.h +1 -0
@@ -556,6 +556,7 @@ void smc_smcd_terminate(struct smcd_dev *dev, struct smcd_gid *peer_gid,void smc_smcd_terminate_all (struct smcd_dev *dev);void smc_smcr_terminate_all (struct smc_ib_device *smcibdev);int smc_buf_create (struct smc_sock *smc,bool is_smcd); +int smcd_buf_attach (struct smc_sock *smc);int smc_uncompress_bufsize (u8 compressed);int smc_rmb_rtoken_handling (struct smc_connection *conn,struct smc_link *link,struct smc_clc_msg_accept_confirm *clc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 42/356 net/smc: refactoring initialization of smc sock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: D. Wythe <[email protected]>
[ Upstream commit d0e35656d83458d668593930f1568d464dde429c ]
This patch aims to isolate the shared components of SMC socket allocation by introducing smc_sk_init() for sock initialization and __smc_create_clcsk() for the initialization of clcsock.
This is in preparation for the subsequent implementation of the AF_INET version of SMC.
Stable-dep-of: 0541db8ee32c ("net/smc: initialize close_work early to avoid warning")
--- net/smc/af_smc.c | 86 +++++++++++++++++++++++++++--------------------- net/smc/smc.h | 5 +++ 2 files changed, 53 insertions(+), 38 deletions(-)
net/smc/af_smc.c +48 -38
@@ -362,25 +362,15 @@ static void smc_destruct(struct sock *sk)return ; } -static struct sock *smc_sock_alloc (struct net *net,struct socket *sock, -int protocol) +void smc_sk_init (struct net *net,struct sock *sk,int protocol) { -struct smc_sock *smc; -struct proto *prot; -struct sock *sk; - - prot = (protocol ==SMCPROTO_SMC6 ) ? &smc_proto6 : &smc_proto; - sk =sk_alloc (net,PF_SMC ,GFP_KERNEL , prot,0 ); -if (!sk) -return NULL ; +struct smc_sock *smc =smc_sk (sk); -sock_init_data (sock, sk);/* sets sk_refcnt to 1 */ sk->sk_state =SMC_INIT ; sk->sk_destruct = smc_destruct; sk->sk_protocol = protocol;WRITE_ONCE (sk->sk_sndbuf,2 *READ_ONCE (net->smc.sysctl_wmem));WRITE_ONCE (sk->sk_rcvbuf,2 *READ_ONCE (net->smc.sysctl_rmem)); - smc =smc_sk (sk);INIT_WORK (&smc->tcp_listen_work, smc_tcp_listen_work);INIT_WORK (&smc->connect_work, smc_connect_work);INIT_DELAYED_WORK (&smc->conn.tx_work, smc_tx_work);
@@ -390,6 +380,24 @@ static struct sock *smc_sock_alloc(struct net *net, struct socket *sock, sk->sk_prot->hash (sk);mutex_init (&smc->clcsock_release_lock);smc_init_saved_callbacks (smc); + smc->limit_smc_hs = net->smc.limit_smc_hs; + smc->use_fallback = false;/* assume rdma capability first */ + smc->fallback_rsn =0 ; +} + +static struct sock *smc_sock_alloc (struct net *net,struct socket *sock, +int protocol) +{ +struct proto *prot; +struct sock *sk; + + prot = (protocol ==SMCPROTO_SMC6 ) ? &smc_proto6 : &smc_proto; + sk =sk_alloc (net,PF_SMC ,GFP_KERNEL , prot,0 ); +if (!sk) +return NULL ; + +sock_init_data (sock, sk);/* sets sk_refcnt to 1 */ +smc_sk_init (net, sk, protocol);return sk; }
@@ -3303,6 +3311,31 @@ static const struct proto_ops smc_sock_ops = { .splice_read = smc_splice_read, }; +int smc_create_clcsk (struct net *net,struct sock *sk,int family) +{ +struct smc_sock *smc =smc_sk (sk); +int rc; + + rc =sock_create_kern (net, family,SOCK_STREAM ,IPPROTO_TCP , + &smc->clcsock); +if (rc) { +sk_common_release (sk); +return rc; + } + +/* smc_clcsock_release() does not wait smc->clcsock->sk's +* destruction; its sk_state might not be TCP_CLOSE after +* smc->sk is close()d, and TCP timers can be fired later, +* which need net ref. +*/ + sk = smc->clcsock->sk; +__netns_tracker_free (net, &sk->ns_tracker, false); + sk->sk_net_refcnt =1 ; +get_net_track (net, &sk->ns_tracker,GFP_KERNEL ); +sock_inuse_add (net,1 ); +return 0 ; +} +static int __smc_create (struct net *net,struct socket *sock,int protocol,int kern,struct socket *clcsock) {
@@ -3328,35 +3361,12 @@ static int __smc_create(struct net *net, struct socket *sock, int protocol,/* create internal TCP socket for CLC handshake and fallback */ smc =smc_sk (sk); - smc->use_fallback = false;/* assume rdma capability first */ - smc->fallback_rsn =0 ; - -/* default behavior from limit_smc_hs in every net namespace */ - smc->limit_smc_hs = net->smc.limit_smc_hs; rc =0 ; -if (!clcsock) { - rc =sock_create_kern (net, family,SOCK_STREAM ,IPPROTO_TCP , - &smc->clcsock); -if (rc) { -sk_common_release (sk); - goto out; - } - -/* smc_clcsock_release() does not wait smc->clcsock->sk's -* destruction; its sk_state might not be TCP_CLOSE after -* smc->sk is close()d, and TCP timers can be fired later, -* which need net ref. -*/ - sk = smc->clcsock->sk; -__netns_tracker_free (net, &sk->ns_tracker, false); - sk->sk_net_refcnt =1 ; -get_net_track (net, &sk->ns_tracker,GFP_KERNEL ); -sock_inuse_add (net,1 ); - }else { +if (clcsock) smc->clcsock = clcsock; - } - +else + rc =smc_create_clcsk (net, sk, family); out:return rc; }
net/smc/smc.h +5 -0
@@ -34,6 +34,11 @@extern struct proto smc_proto;extern struct proto smc_proto6; +/* smc sock initialization */ +void smc_sk_init (struct net *net,struct sock *sk,int protocol); +/* clcsock initialization */ +int smc_create_clcsk (struct net *net,struct sock *sk,int family); +#ifdef ATOMIC64_INIT #define KERNEL_HAS_ATOMIC64 #endif
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 43/356 net/smc: initialize close_work early to avoid warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 0541db8ee32c09463a72d0987382b3a3336b0043 ]
We encountered a warning that close_work was canceled before initialization.
WARNING: CPU: 7 PID: 111103 at kernel/workqueue.c:3047 __flush_work+0x19e/0x1b0 Workqueue: events smc_lgr_terminate_work [smc] RIP: 0010:__flush_work+0x19e/0x1b0 Call Trace: ? __wake_up_common+0x7a/0x190 ? work_busy+0x80/0x80 __cancel_work_timer+0xe3/0x160 smc_close_cancel_work+0x1a/0x70 [smc] smc_close_active_abort+0x207/0x360 [smc] __smc_lgr_terminate.part.38+0xc8/0x180 [smc] process_one_work+0x19e/0x340 worker_thread+0x30/0x370 ? process_one_work+0x340/0x340 kthread+0x117/0x130 ? __kthread_cancel_work+0x50/0x50 ret_from_fork+0x22/0x30
This is because when smc_close_cancel_work is triggered, e.g. the RDMA driver is rmmod and the LGR is terminated, the conn->close_work is flushed before initialization, resulting in WARN_ON(!work->func).
__smc_lgr_terminate | smc_connect_{rdma|ism}
-------------------------------------------------------------
| smc_conn_create | \- smc_lgr_register_conn
for conn in lgr->conns_all |
\- smc_conn_kill |
\- smc_close_active_abort |
\- smc_close_cancel_work |
\- cancel_work_sync |
\- __flush_work |
(close_work) |
| smc_close_init
| \- INIT_WORK(&close_work)So fix this by initializing close_work before establishing the connection.
--- net/smc/af_smc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
net/smc/af_smc.c +1 -3
@@ -383,6 +383,7 @@ void smc_sk_init(struct net *net, struct sock *sk, int protocol) smc->limit_smc_hs = net->smc.limit_smc_hs; smc->use_fallback = false;/* assume rdma capability first */ smc->fallback_rsn =0 ; +smc_close_init (smc); } static struct sock *smc_sock_alloc(struct net *net, struct socket *sock,
@@ -1298,7 +1299,6 @@ static int smc_connect_rdma(struct smc_sock *smc, goto connect_abort; } -smc_close_init (smc);smc_rx_init (smc);if (ini->first_contact_local) {
@@ -1434,7 +1434,6 @@ static int smc_connect_ism(struct smc_sock *smc, goto connect_abort; } } -smc_close_init (smc);smc_rx_init (smc);smc_tx_init (smc);
@@ -2486,7 +2485,6 @@ static void smc_listen_work(struct work_struct *work) goto out_decl;mutex_lock (&smc_server_lgr_pending); -smc_close_init (new_smc);smc_rx_init (new_smc);smc_tx_init (new_smc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 44/356 net/smc: fix LGR and link use-after-free issue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wen Gu <[email protected]>
[ Upstream commit 2c7f14ed9c19ec0f149479d1c2842ec1f9bf76d7 ]
We encountered a LGR/link use-after-free issue, which manifested as the LGR/link refcnt reaching 0 early and entering the clear process, making resource access unsafe.
refcount_t: addition on 0; use-after-free.
WARNING: CPU: 14 PID: 107447 at lib/refcount.c:25 refcount_warn_saturate+0x9c/0x140 Workqueue: events smc_lgr_terminate_work [smc] Call trace: refcount_warn_saturate+0x9c/0x140 __smc_lgr_terminate.part.45+0x2a8/0x370 [smc] smc_lgr_terminate_work+0x28/0x30 [smc] process_one_work+0x1b8/0x420 worker_thread+0x158/0x510 kthread+0x114/0x118
or
refcount_t: underflow; use-after-free.
WARNING: CPU: 6 PID: 93140 at lib/refcount.c:28 refcount_warn_saturate+0xf0/0x140 Workqueue: smc_hs_wq smc_listen_work [smc] Call trace: refcount_warn_saturate+0xf0/0x140 smcr_link_put+0x1cc/0x1d8 [smc] smc_conn_free+0x110/0x1b0 [smc] smc_conn_abort+0x50/0x60 [smc] smc_listen_find_device+0x75c/0x790 [smc] smc_listen_work+0x368/0x8a0 [smc] process_one_work+0x1b8/0x420 worker_thread+0x158/0x510 kthread+0x114/0x118
It is caused by repeated release of LGR/link refcnt. One suspect is that smc_conn_free() is called repeatedly because some smc_conn_free() from server listening path are not protected by sock lock.
e.g.
Calls under socklock | smc_listen_work
-------------------------------------------------------
lock_sock(sk) | smc_conn_abort smc_conn_free | \- smc_conn_free \- smcr_link_put | \- smcr_link_put (duplicated)
release_sock(sk)
So here add sock lock protection in smc_listen_work() path, making it exclusive with other connection operations.
--- net/smc/af_smc.c | 2 ++ 1 file changed, 2 insertions(+)
net/smc/af_smc.c +2 -0
@@ -1907,6 +1907,7 @@ static void smc_listen_out(struct smc_sock *new_smc)if (tcp_sk (new_smc->clcsock->sk)->syn_smc)atomic_dec (&lsmc->queued_smc_hs); +release_sock (newsmcsk);/* lock in smc_listen_work() */ if (lsmc->sk.sk_state ==SMC_LISTEN ) {lock_sock_nested (&lsmc->sk,SINGLE_DEPTH_NESTING );smc_accept_enqueue (&lsmc->sk, newsmcsk);
@@ -2428,6 +2429,7 @@ static void smc_listen_work(struct work_struct *work)u8 accept_version;int rc =0 ; +lock_sock (&new_smc->sk);/* release in smc_listen_out() */ if (new_smc->listen_smc->sk.sk_state !=SMC_LISTEN )return smc_listen_out_err (new_smc);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 45/356 net/qed: allow old cards not supporting "num_images" to work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Louis Leseur <[email protected]>
[ Upstream commit 7a0ea70da56ee8c2716d0b79e9959d3c47efab62 ]
Commit 43645ce03e00 ("qed: Populate nvm image attribute shadow.") added support for populating flash image attributes, notably "num_images". However, some cards were not able to return this information. In such cases, the driver would return EINVAL, causing the driver to exit.
Add check to return EOPNOTSUPP instead of EINVAL when the card is not able to return these information. The caller function already handles EOPNOTSUPP without error.
--- drivers/net/ethernet/qlogic/qed/qed_mcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/qlogic/qed/qed_mcp.c +3 -1
@@ -3314,7 +3314,9 @@ int qed_mcp_bist_nvm_get_num_images(struct qed_hwfn *p_hwfn,if (rc)return rc; -if (((rsp &FW_MSG_CODE_MASK ) !=FW_MSG_CODE_OK )) +if (((rsp &FW_MSG_CODE_MASK ) ==FW_MSG_CODE_UNSUPPORTED )) + rc = -EOPNOTSUPP ; +else if (((rsp &FW_MSG_CODE_MASK ) !=FW_MSG_CODE_OK )) rc = -EINVAL ;return rc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 46/356 ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Keller <[email protected]>
[ Upstream commit d0725312adf5a803de8f621bd1b12ba7a6464a29 ]
Commit 339f28964147 ("ixgbevf: Add support for new mailbox communication between PF and VF") added support for v1.5 of the PF to VF mailbox communication API. This commit mistakenly enabled IPSEC offload for API v1.5.
No implementation of the v1.5 API has support for IPSEC offload. This offload is only supported by the Linux PF as mailbox API v1.4. In fact, the v1.5 API is not implemented in any Linux PF.
Attempting to enable IPSEC offload on a PF which supports v1.5 API will not work. Only the Linux upstream ixgbe and ixgbevf support IPSEC offload, and only as part of the v1.4 API.
Fix the ixgbevf Linux driver to stop attempting IPSEC offload when the mailbox API does not support it.
The existing API design choice makes it difficult to support future API versions, as other non-Linux hosts do not implement IPSEC offload. If we add support for v1.5 to the Linux PF, then we lose support for IPSEC offload.
A full solution likely requires a new mailbox API with a proper negotiation to check that IPSEC is actually supported by the host.
--- drivers/net/ethernet/intel/ixgbevf/ipsec.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/intel/ixgbevf/ipsec.c +0 -1
@@ -629,7 +629,6 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter)switch (adapter->hw.api_version) {case ixgbe_mbox_api_14: -case ixgbe_mbox_api_15:break ;default :return ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 47/356 ixgbe: downgrade logging of unsupported VF API version to debug
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Keller <[email protected]>
[ Upstream commit 15915b43a7fb938934bb7fc4290127218859d795 ]
The ixgbe PF driver logs an info message when a VF attempts to negotiate an API version which it does not support:
VF 0 requested invalid api version 6
The ixgbevf driver attempts to load with mailbox API v1.5, which is required for best compatibility with other hosts such as the ESX VMWare PF.
The Linux PF only supports API v1.4, and does not currently have support for the v1.5 API.
The logged message can confuse users, as the v1.5 API is valid, but just happens to not currently be supported by the Linux PF.
Downgrade the info message to a debug message, and fix the language to use 'unsupported' instead of 'invalid' to improve message clarity.
Long term, we should investigate whether the improvements in the v1.5 API make sense for the Linux PF, and if so implement them properly. This may require yet another API version to resolve issues with negotiating IPSEC offload support.
--- drivers/net/ethernet/intel/ixgbe/ixgbe_common.h | 2 ++ drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h +2 -0
@@ -194,6 +194,8 @@ u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg); dev_err(&adapter->pdev->dev, format, ## arg) #define e_dev_notice(format, arg...) \ dev_notice(&adapter->pdev->dev, format, ## arg) +#define e_dbg(msglvl, format, arg...) \ + netif_dbg(adapter, msglvl, adapter->netdev, format, ## arg) #define e_info(msglvl, format, arg...) \ netif_info(adapter, msglvl, adapter->netdev, format, ## arg) #define e_err(msglvl, format, arg...) \
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +1 -1
@@ -1049,7 +1049,7 @@ static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,break ; } -e_info (drv,"VF %d requested invalid api version %u\n" , vf, api); +e_dbg (drv,"VF %d requested unsupported api version %u\n" , vf, api);return -1 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 48/356 igb: Fix potential invalid memory access in igb_init_module()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Can <[email protected]>
[ Upstream commit 0566f83d206c7a864abcd741fe39d6e0ae5eef29 ]
The pci_register_driver() can fail and when this happened, the dca_notifier needs to be unregistered, otherwise the dca_notifier can be called when igb fails to install, resulting to invalid memory access.
--- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/intel/igb/igb_main.c +4 -0
@@ -665,6 +665,10 @@ static int __init igb_init_module(void)dca_register_notify (&dca_notifier);#endif ret =pci_register_driver (&igb_driver); +#ifdef CONFIG_IGB_DCA +if (ret) +dca_unregister_notify (&dca_notifier); +#endif return ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 49/356 netfilter: nft_inner: incorrect percpu area handling under softirq
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 7b1d83da254be3bf054965c8f3b1ad976f460ae5 ]
Softirq can interrupt ongoing packet from process context that is walking over the percpu area that contains inner header offsets.
Disable bh and perform three checks before restoring the percpu inner header offsets to validate that the percpu area is valid for this skbuff:
1) If the NFT_PKTINFO_INNER_FULL flag is set on, then this skbuff has already been parsed before for inner header fetching to register.
2) Validate that the percpu area refers to this skbuff using the skbuff pointer as a cookie. If there is a cookie mismatch, then this skbuff needs to be parsed again.
3) Finally, validate if the percpu area refers to this tunnel type.
Only after these three checks the percpu area is restored to a on-stack copy and bh is enabled again.
After inner header fetching, the on-stack copy is stored back to the percpu area.
--- include/net/netfilter/nf_tables_core.h | 1 + net/netfilter/nft_inner.c | 57 ++++++++++++++++++++------ 2 files changed, 46 insertions(+), 12 deletions(-)
include/net/netfilter/nf_tables_core.h +1 -0
@@ -161,6 +161,7 @@ enum { };struct nft_inner_tun_ctx { +unsigned long cookie;u16 type;u16 inner_tunoff;u16 inner_lloff;
net/netfilter/nft_inner.c +45 -12
107 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 50/356 net: sched: fix erspan_opt settings in cls_flower
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <[email protected]>
[ Upstream commit 292207809486d99c78068d3f459cbbbffde88415 ]
When matching erspan_opt in cls_flower, only the (version, dir, hwid) fields are relevant. However, in fl_set_erspan_opt() it initializes all bits of erspan_opt and its mask to 1. This inadvertently requires packets to match not only the (version, dir, hwid) fields but also the other fields that are unexpectedly set to 1.
This patch resolves the issue by ensuring that only the (version, dir, hwid) fields are configured in fl_set_erspan_opt(), leaving the other fields to 0 in erspan_opt.
--- net/sched/cls_flower.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/sched/cls_flower.c +3 -2
@@ -1320,7 +1320,6 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,int err; md = (struct erspan_metadata *)&key->enc_opts.data[key->enc_opts.len]; -memset (md,0xff ,sizeof (*md)); md->version =1 ;if (!depth)
@@ -1349,9 +1348,9 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,NL_SET_ERR_MSG (extack,"Missing tunnel key erspan option index" );return -EINVAL ; } +memset (&md->u.index,0xff ,sizeof (md->u.index));if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_INDEX ]; -memset (&md->u,0x00 ,sizeof (md->u)); md->u.index =nla_get_be32 (nla); } }else if (md->version ==2 ) {
@@ -1360,10 +1359,12 @@ static int fl_set_erspan_opt(const struct nlattr *nla, struct fl_flow_key *key,NL_SET_ERR_MSG (extack,"Missing tunnel key erspan option dir or hwid" );return -EINVAL ; } + md->u.md2.dir =1 ;if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_DIR ]; md->u.md2.dir =nla_get_u8 (nla); } +set_hwid (&md->u.md2,0xff );if (tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID ]) { nla = tb[TCA_FLOWER_KEY_ENC_OPT_ERSPAN_HWID ];set_hwid (&md->u.md2,nla_get_u8 (nla));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 51/356 netfilter: ipset: Hold module reference while requesting a module
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <[email protected]>
[ Upstream commit 456f010bfaefde84d3390c755eedb1b0a5857c3c ]
User space may unload ip_set.ko while it is itself requesting a set type backend module, leading to a kernel crash. The race condition may be provoked by inserting an mdelay() right after the nfnl_unlock() call.
--- net/netfilter/ipset/ip_set_core.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netfilter/ipset/ip_set_core.c +5 -0
@@ -104,14 +104,19 @@ find_set_type(const char *name, u8 family, u8 revision)static bool load_settype (const char *name) { +if (!try_module_get (THIS_MODULE )) +return false; +nfnl_unlock (NFNL_SUBSYS_IPSET );pr_debug ("try to load ip_set_%s\n" , name);if (request_module ("ip_set_%s" , name) <0 ) {pr_warn ("Can't find ip_set type %s\n" , name);nfnl_lock (NFNL_SUBSYS_IPSET ); +module_put (THIS_MODULE );return false; }nfnl_lock (NFNL_SUBSYS_IPSET ); +module_put (THIS_MODULE );return true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 52/356 netfilter: nft_set_hash: skip duplicated elements pending gc run
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 7ffc7481153bbabf3332c6a19b289730c7e1edf5 ]
rhashtable does not provide stable walk, duplicated elements are possible in case of resizing. I considered that checking for errors when calling rhashtable_walk_next() was sufficient to detect the resizing. However, rhashtable_walk_next() returns -EAGAIN only at the end of the iteration, which is too late, because a gc work containing duplicated elements could have been already scheduled for removal to the worker.
Add a u32 gc worker sequence number per set, bump it on every workqueue run. Annotate gc worker sequence number on the expired element. Use it to skip those already seen in this gc workqueue run.
Note that this new field is never reset in case gc transaction fails, so next gc worker run on the expired element overrides it. Wraparound of gc worker sequence number should not be an issue with stale gc worker sequence number in the element, that would just postpone the element removal in one gc run.
Note that it is not possible to use flags to annotate that element is pending gc run to detect duplicates, given that gc transaction can be invalidated in case of update from the control plane, therefore, not allowing to clear such flag.
On x86_64, pahole reports no changes in the size of nft_rhash_elem.
--- net/netfilter/nft_set_hash.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
net/netfilter/nft_set_hash.c +16 -0
@@ -24,10 +24,12 @@struct nft_rhash {struct rhashtable ht;struct delayed_work gc_work; +u32 wq_gc_seq; };struct nft_rhash_elem {struct rhash_head node; +u32 wq_gc_seq;struct nft_set_ext ext; };
@@ -331,6 +333,10 @@ static void nft_rhash_gc(struct work_struct *work)if (!gc) goto done; +/* Elements never collected use a zero gc worker sequence number. */ +if (unlikely (++priv->wq_gc_seq ==0 )) + priv->wq_gc_seq++; +rhashtable_walk_enter (&priv->ht, &hti);rhashtable_walk_start (&hti);
@@ -348,6 +354,14 @@ static void nft_rhash_gc(struct work_struct *work) goto try_later; } +/* rhashtable walk is unstable, already seen in this gc run? +* Then, skip this element. In case of (unlikely) sequence +* wraparound and stale element wq_gc_seq, next gc run will +* just find this expired element. +*/ +if (he->wq_gc_seq == priv->wq_gc_seq) +continue ; +if (nft_set_elem_is_dead (&he->ext)) goto dead_elem;
@@ -364,6 +378,8 @@ static void nft_rhash_gc(struct work_struct *work)if (!gc) goto try_later; +/* annotate gc sequence for this attempt. */ + he->wq_gc_seq = priv->wq_gc_seq;nft_trans_gc_elem_add (gc, he); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 53/356 ethtool: Fix wrong mod state in case of verbose and no_mask bitset
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kory Maincent <[email protected]>
[ Upstream commit 910c4788d6155b2202ec88273376cd7ecdc24f0a ]
A bitset without mask in a _SET request means we want exactly the bits in the bitset to be set. This works correctly for compact format but when verbose format is parsed, ethnl_update_bitset32_verbose() only sets the bits present in the request bitset but does not clear the rest. The commit 6699170376ab ("ethtool: fix application of verbose no_mask bitset") fixes this issue by clearing the whole target bitmap before we start iterating. The solution proposed brought an issue with the behavior of the mod variable. As the bitset is always cleared the old value will always differ to the new value.
Fix it by adding a new function to compare bitmaps and a temporary variable which save the state of the old bitmap.
--- net/ethtool/bitset.c | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-)
net/ethtool/bitset.c +44 -4
@@ -425,12 +425,32 @@ static int ethnl_parse_bit(unsigned int *index, bool *val, unsigned int nbits,return 0 ; } +/** +* ethnl_bitmap32_equal() - Compare two bitmaps +* @map1: first bitmap +* @map2: second bitmap +* @nbits: bit size to compare +* +* Return: true if first @nbits are equal, false if not +*/ +static bool ethnl_bitmap32_equal (const u32 *map1,const u32 *map2, +unsigned int nbits) +{ +if (memcmp (map1, map2, nbits /32 *sizeof (u32))) +return false; +if (nbits %32 ==0 ) +return true; +return !((map1[nbits /32 ] ^ map2[nbits /32 ]) & +ethnl_lower_bits (nbits %32 )); +} +static int ethnl_update_bitset32_verbose (u32 *bitmap,unsigned int nbits,const struct nlattr *attr,struct nlattr **tb,ethnl_string_array_t names,struct netlink_ext_ack *extack,bool *mod) { +u32 *saved_bitmap =NULL ;struct nlattr *bit_attr;bool no_mask;int rem;
@@ -448,8 +468,20 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits, } no_mask = tb[ETHTOOL_A_BITSET_NOMASK ]; -if (no_mask) -ethnl_bitmap32_clear (bitmap,0 , nbits, mod); +if (no_mask) { +unsigned int nwords =DIV_ROUND_UP (nbits,32 ); +unsigned int nbytes = nwords *sizeof (u32); +bool dummy; + +/* The bitmap size is only the size of the map part without +* its mask part. +*/ + saved_bitmap =kcalloc (nwords,sizeof (u32),GFP_KERNEL ); +if (!saved_bitmap) +return -ENOMEM ; +memcpy (saved_bitmap, bitmap, nbytes); +ethnl_bitmap32_clear (bitmap,0 , nbits, &dummy); + }nla_for_each_nested (bit_attr, tb[ETHTOOL_A_BITSET_BITS ], rem) {bool old_val, new_val;
@@ -458,22 +490,30 @@ ethnl_update_bitset32_verbose(u32 *bitmap, unsigned int nbits,if (nla_type (bit_attr) !=ETHTOOL_A_BITSET_BITS_BIT ) {NL_SET_ERR_MSG_ATTR (extack, bit_attr,"only ETHTOOL_A_BITSET_BITS_BIT allowed in ETHTOOL_A_BITSET_BITS" ); +kfree (saved_bitmap);return -EINVAL ; } ret =ethnl_parse_bit (&idx, &new_val, nbits, bit_attr, no_mask, names, extack); -if (ret <0 ) +if (ret <0 ) { +kfree (saved_bitmap);return ret; + } old_val = bitmap[idx /32 ] & ((u32 )1 << (idx %32 ));if (new_val != old_val) {if (new_val) bitmap[idx /32 ] |= ((u32 )1 << (idx %32 ));else bitmap[idx /32 ] &= ~((u32 )1 << (idx %32 )); - *mod = true; +if (!no_mask) + *mod = true; } } +if (no_mask && !ethnl_bitmap32_equal (saved_bitmap, bitmap, nbits)) + *mod = true; + +kfree (saved_bitmap);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 54/356 mlxsw: Add ipv4_5 flex key
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Cohen <[email protected]>
[ Upstream commit c2f3e10ac4ebf23e177226b9b4d297bfe2fb6b20 ]
Currently virtual router ID element is broken to two sub-elements - 'VIRT_ROUTER_LSB' and 'VIRT_ROUTER_MSB'. It was broken as this field is broken in 'ipv4_4' flex key which is used for IPv4 in Spectrum < 4. For Spectrum-4, we use 'ipv4_4b' flex key which contains one field for virtual router, this key is not supported in older ASICs.
Add 'ipv4_5' flex key which is supported in all ASICs and contains one field for virtual router. Then there is no reason to use 'VIRT_ROUTER_LSB' and 'VIRT_ROUTER_MSB', remove them and add one element 'VIRT_ROUTER' for this field.
The motivation is to get rid of 'ipv4_4' flex key, as it might be chosen for IPv6 multicast forwarding region. This will not allow the improvement in a following patch. See more details in the cover letter and in a following patch.
Stable-dep-of: 217bbf156f93 ("mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4")
--- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.c | 3 +-- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 3 +-- .../net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c | 13 ++++--------- .../mellanox/mlxsw/spectrum_acl_flex_keys.c | 10 ++++------ 4 files changed, 10 insertions(+), 19 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +1 -2
@@ -33,8 +33,7 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {MLXSW_AFK_ELEMENT_INFO_U32 (IP_TTL_ ,0x18 ,0 ,8 ),MLXSW_AFK_ELEMENT_INFO_U32 (IP_ECN ,0x18 ,9 ,2 ),MLXSW_AFK_ELEMENT_INFO_U32 (IP_DSCP ,0x18 ,11 ,6 ), -MLXSW_AFK_ELEMENT_INFO_U32 (VIRT_ROUTER_MSB ,0x18 ,17 ,4 ), -MLXSW_AFK_ELEMENT_INFO_U32 (VIRT_ROUTER_LSB ,0x18 ,21 ,8 ), +MLXSW_AFK_ELEMENT_INFO_U32 (VIRT_ROUTER ,0x18 ,17 ,12 ),MLXSW_AFK_ELEMENT_INFO_BUF (SRC_IP_96_127 ,0x20 ,4 ),MLXSW_AFK_ELEMENT_INFO_BUF (SRC_IP_64_95 ,0x24 ,4 ), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +1 -2
@@ -33,8 +33,7 @@ enum mlxsw_afk_element {MLXSW_AFK_ELEMENT_IP_TTL_ ,MLXSW_AFK_ELEMENT_IP_ECN ,MLXSW_AFK_ELEMENT_IP_DSCP , -MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , -MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB , +MLXSW_AFK_ELEMENT_VIRT_ROUTER ,MLXSW_AFK_ELEMENT_FDB_MISS ,MLXSW_AFK_ELEMENT_L4_PORT_RANGE , MLXSW_AFK_ELEMENT_MAX,
drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c +4 -9
@@ -45,8 +45,7 @@ static int mlxsw_sp2_mr_tcam_bind_group(struct mlxsw_sp *mlxsw_sp, }static const enum mlxsw_afk_element mlxsw_sp2_mr_tcam_usage_ipv4[] = { -MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , -MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB , +MLXSW_AFK_ELEMENT_VIRT_ROUTER ,MLXSW_AFK_ELEMENT_SRC_IP_0_31 ,MLXSW_AFK_ELEMENT_DST_IP_0_31 , };
@@ -89,8 +88,7 @@ static void mlxsw_sp2_mr_tcam_ipv4_fini(struct mlxsw_sp2_mr_tcam *mr_tcam) }static const enum mlxsw_afk_element mlxsw_sp2_mr_tcam_usage_ipv6[] = { -MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , -MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB , +MLXSW_AFK_ELEMENT_VIRT_ROUTER ,MLXSW_AFK_ELEMENT_SRC_IP_96_127 ,MLXSW_AFK_ELEMENT_SRC_IP_64_95 ,MLXSW_AFK_ELEMENT_SRC_IP_32_63 ,
@@ -189,11 +187,8 @@ mlxsw_sp2_mr_tcam_rule_parse(struct mlxsw_sp_acl_rule *rule, rulei =mlxsw_sp_acl_rule_rulei (rule); rulei->priority = priority; -mlxsw_sp_acl_rulei_keymask_u32 (rulei,MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB , - key->vrid,GENMASK (7 ,0 )); -mlxsw_sp_acl_rulei_keymask_u32 (rulei, -MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , - key->vrid >>8 ,GENMASK (3 ,0 )); +mlxsw_sp_acl_rulei_keymask_u32 (rulei,MLXSW_AFK_ELEMENT_VIRT_ROUTER , + key->vrid,GENMASK (11 ,0 ));switch (key->proto) {case MLXSW_SP_L3_PROTO_IPV4 :return mlxsw_sp2_mr_tcam_rule_parse4 (rulei, key);
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +4 -6
@@ -171,9 +171,8 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = { MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x04, 16, 8), }; -static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4[] = { -MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_LSB ,0x04 ,24 ,8 ), -MLXSW_AFK_ELEMENT_INST_EXT_U32 (VIRT_ROUTER_MSB ,0x00 ,0 ,3 ,0 , true), +static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5[] = { +MLXSW_AFK_ELEMENT_INST_EXT_U32 (VIRT_ROUTER ,0x04 ,20 ,11 ,0 , true), };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {
@@ -220,7 +219,7 @@ static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {MLXSW_AFK_BLOCK (0x38 , mlxsw_sp_afk_element_info_ipv4_0),MLXSW_AFK_BLOCK (0x39 , mlxsw_sp_afk_element_info_ipv4_1),MLXSW_AFK_BLOCK (0x3A , mlxsw_sp_afk_element_info_ipv4_2), -MLXSW_AFK_BLOCK (0x3C , mlxsw_sp_afk_element_info_ipv4_4), +MLXSW_AFK_BLOCK (0x3D , mlxsw_sp_afk_element_info_ipv4_5),MLXSW_AFK_BLOCK (0x40 , mlxsw_sp_afk_element_info_ipv6_0),MLXSW_AFK_BLOCK (0x41 , mlxsw_sp_afk_element_info_ipv6_1), MLXSW_AFK_BLOCK(0x42, mlxsw_sp_afk_element_info_ipv6_2),
@@ -323,8 +322,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = { };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4b[] = { -MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_LSB ,0x04 ,13 ,8 ), -MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_MSB ,0x04 ,21 ,4 ), +MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER ,0x04 ,13 ,12 ), };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 55/356 mlxsw: spectrum_acl_flex_keys: Add ipv4_5b flex key
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Cohen <[email protected]>
[ Upstream commit c6caabdf3e0cc50ba4a44bebc82cda5551d81d4f ]
The previous patch replaced the key block 'ipv4_4' with 'ipv4_5'. The corresponding block for Spectrum-4 is 'ipv4_4b'. To be consistent, replace key block 'ipv4_4b' with 'ipv4_5b'.
Stable-dep-of: 217bbf156f93 ("mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4")
--- .../net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +3 -3
@@ -321,8 +321,8 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = { MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */ }; -static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4b[] = { -MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER ,0x04 ,13 ,12 ), +static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = { +MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER ,0x04 ,20 ,12 ), };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {
@@ -339,7 +339,7 @@ static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = {MLXSW_AFK_BLOCK (0x38 , mlxsw_sp_afk_element_info_ipv4_0),MLXSW_AFK_BLOCK (0x39 , mlxsw_sp_afk_element_info_ipv4_1),MLXSW_AFK_BLOCK (0x3A , mlxsw_sp_afk_element_info_ipv4_2), -MLXSW_AFK_BLOCK (0x35 , mlxsw_sp_afk_element_info_ipv4_4b), +MLXSW_AFK_BLOCK (0x36 , mlxsw_sp_afk_element_info_ipv4_5b),MLXSW_AFK_BLOCK (0x40 , mlxsw_sp_afk_element_info_ipv6_0),MLXSW_AFK_BLOCK (0x41 , mlxsw_sp_afk_element_info_ipv6_1), MLXSW_AFK_BLOCK(0x47, mlxsw_sp_afk_element_info_ipv6_2b),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 56/356 mlxsw: Edit IPv6 key blocks to use one less block for multicast forwarding
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Cohen <[email protected]>
[ Upstream commit 92953e7aab013719aa8974805614c0bc11361026 ]
Two ACL regions that are configured by the driver during initialization are the ones used for IPv4 and IPv6 multicast forwarding. Entries residing in these two regions match on the {SIP, DIP, VRID} key elements.
Currently for IPv6 region, 9 key blocks are used:
* 4 for SIP - 'ipv4_1', 'ipv6_{3,4,5}'
* 4 for DIP - 'ipv4_0', 'ipv6_{0,1,2/2b}'
* 1 for VRID - 'ipv4_4b'
This can be improved by reducing the amount key blocks needed for the IPv6 region to 8. It is possible to use key blocks that mix subsets of the VRID element with subsets of the DIP element.
The following key blocks can be used:
* 4 for SIP - 'ipv4_1', 'ipv6_{3,4,5}'
* 1 for subset of DIP - 'ipv4_0'
* 3 for the rest of DIP and subsets of VRID - 'ipv6_{0,1,2/2b}'
To make this happen, add VRID sub-elements as part of existing keys - 'ipv6_{0,1,2/2b}'. Note that one of the sub-elements is called VRID_ROUTER_MSB and does not contain bit numbers like the rest, as for Spectrum < 4 this element represents bits 8-10 and for Spectrum-4 it represents bits 8-11.
Breaking VRID into 3 sub-elements makes the driver use one less block in IPv6 region for multicast forwarding. The sub-elements can be filled in blocks that are used for destination IP.
The algorithm in the driver that chooses which key blocks will be used is lazy and not the optimal one. It searches the block that contains the most elements that are required, chooses it, removes the elements that appear in the chosen block and starts again searching the block that contains the most elements.
When key block 'ipv4_4' is defined, the algorithm might choose it, as it contains 2 sub-elements of VRID, then 8 blocks must be chosen for SIP and DIP and we get 9 blocks to match on {SIP, DIP, VRID}. That is why we had to remove key block 'ipv4_4' in a previous patch and use key block that contains one field for VRID.
This improvement was tested and indeed 8 blocks are used instead of 9.
Stable-dep-of: 217bbf156f93 ("mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4")
--- .../ethernet/mellanox/mlxsw/core_acl_flex_keys.c | 3 +++ .../ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 3 +++ .../ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c | 15 ++++++++++++--- .../mellanox/mlxsw/spectrum_acl_flex_keys.c | 4 ++++ 4 files changed, 22 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +3 -0
@@ -44,6 +44,9 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {MLXSW_AFK_ELEMENT_INFO_BUF (DST_IP_0_31 ,0x3C ,4 ),MLXSW_AFK_ELEMENT_INFO_U32 (FDB_MISS ,0x40 ,0 ,1 ),MLXSW_AFK_ELEMENT_INFO_U32 (L4_PORT_RANGE ,0x40 ,1 ,16 ), +MLXSW_AFK_ELEMENT_INFO_U32 (VIRT_ROUTER_0_3 ,0x40 ,17 ,4 ), +MLXSW_AFK_ELEMENT_INFO_U32 (VIRT_ROUTER_4_7 ,0x40 ,21 ,4 ), + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_MSB, 0x40, 25, 4), }; struct mlxsw_afk {
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +3 -0
@@ -36,6 +36,9 @@ enum mlxsw_afk_element {MLXSW_AFK_ELEMENT_VIRT_ROUTER ,MLXSW_AFK_ELEMENT_FDB_MISS ,MLXSW_AFK_ELEMENT_L4_PORT_RANGE , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_3 , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_4_7 , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , MLXSW_AFK_ELEMENT_MAX, };
drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c +12 -3
@@ -88,7 +88,9 @@ static void mlxsw_sp2_mr_tcam_ipv4_fini(struct mlxsw_sp2_mr_tcam *mr_tcam) }static const enum mlxsw_afk_element mlxsw_sp2_mr_tcam_usage_ipv6[] = { -MLXSW_AFK_ELEMENT_VIRT_ROUTER , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_3 , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_4_7 , +MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB ,MLXSW_AFK_ELEMENT_SRC_IP_96_127 ,MLXSW_AFK_ELEMENT_SRC_IP_64_95 ,MLXSW_AFK_ELEMENT_SRC_IP_32_63 ,
@@ -140,6 +142,8 @@ static void mlxsw_sp2_mr_tcam_rule_parse4(struct mlxsw_sp_acl_rule_info *rulei, struct mlxsw_sp_mr_route_key *key) { +mlxsw_sp_acl_rulei_keymask_u32 (rulei, MLXSW_AFK_ELEMENT_VIRT_ROUTER, + key->vrid, GENMASK(11, 0));mlxsw_sp_acl_rulei_keymask_buf (rulei,MLXSW_AFK_ELEMENT_SRC_IP_0_31 , (char *) &key->source.addr4, (char *) &key->source_mask.addr4,4 );
@@ -152,6 +156,13 @@ static void mlxsw_sp2_mr_tcam_rule_parse6(struct mlxsw_sp_acl_rule_info *rulei, struct mlxsw_sp_mr_route_key *key) { +mlxsw_sp_acl_rulei_keymask_u32 (rulei, MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_3, + key->vrid, GENMASK(3, 0)); +mlxsw_sp_acl_rulei_keymask_u32 (rulei,MLXSW_AFK_ELEMENT_VIRT_ROUTER_4_7 , + key->vrid >>4 ,GENMASK (3 ,0 )); +mlxsw_sp_acl_rulei_keymask_u32 (rulei, +MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB , + key->vrid >>8 ,GENMASK (3 ,0 ));mlxsw_sp_acl_rulei_keymask_buf (rulei,MLXSW_AFK_ELEMENT_SRC_IP_96_127 , &key->source.addr6.s6_addr[0x0 ], &key->source_mask.addr6.s6_addr[0x0 ],4 );
@@ -187,8 +198,6 @@ mlxsw_sp2_mr_tcam_rule_parse(struct mlxsw_sp_acl_rule *rule, rulei =mlxsw_sp_acl_rule_rulei (rule); rulei->priority = priority; -mlxsw_sp_acl_rulei_keymask_u32 (rulei,MLXSW_AFK_ELEMENT_VIRT_ROUTER , - key->vrid,GENMASK (11 ,0 ));switch (key->proto) {case MLXSW_SP_L3_PROTO_IPV4 :return mlxsw_sp2_mr_tcam_rule_parse4 (rulei, key);
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +4 -0
@@ -176,14 +176,17 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5[] = { };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = { +MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_0_3 ,0x00 ,0 ,4 ),MLXSW_AFK_ELEMENT_INST_BUF (DST_IP_32_63 ,0x04 ,4 ), };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = { +MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_4_7 ,0x00 ,0 ,4 ),MLXSW_AFK_ELEMENT_INST_BUF (DST_IP_64_95 ,0x04 ,4 ), };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = { +MLXSW_AFK_ELEMENT_INST_EXT_U32 (VIRT_ROUTER_MSB ,0x00 ,0 ,3 ,0 , true),MLXSW_AFK_ELEMENT_INST_BUF (DST_IP_96_127 ,0x04 ,4 ), };
@@ -326,6 +329,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = { };static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = { +MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER_MSB ,0x00 ,0 ,4 ),MLXSW_AFK_ELEMENT_INST_BUF (DST_IP_96_127 ,0x04 ,4 ), };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 57/356 mlxsw: Mark high entropy key blocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Cohen <[email protected]>
[ Upstream commit cad6431b867507779c41b00baaf18382467ef0a0 ]
For 12 key blocks in the A-TCAM, rules are split into two records, which constitute two lookups. The two records are linked using a "large entry key ID".
Due to a Spectrum-4 hardware issue, KVD entries that correspond to key blocks 0 to 5 of 12 key blocks A-TCAM entries will be placed in the same KVD pipe if they only differ in their "large entry key ID", as it is ignored. This results in a reduced scale. To reduce the probability of this issue, we can place key blocks with high entropy in blocks 0 to 5. The idea is to place blocks that are changed often in blocks 0 to 5, for example, key blocks that match on IPv4 addresses or the LSBs of IPv6 addresses. Such placement will reduce the probability of these blocks to be same.
Mark several blocks with 'high_entropy' flag, so later we will take into account this flag and place them in blocks 0 to 5.
Stable-dep-of: 217bbf156f93 ("mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4")
--- .../net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h | 9 +++++++++ .../ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c | 12 ++++++------ 2 files changed, 15 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +9 -0
@@ -119,6 +119,7 @@ struct mlxsw_afk_block {u16 encoding;/* block ID */ struct mlxsw_afk_element_inst *instances;unsigned int instances_count; +bool high_entropy; };#define MLXSW_AFK_BLOCK (_encoding, _instances) \
@@ -128,6 +129,14 @@ struct mlxsw_afk_block { .instances_count = ARRAY_SIZE(_instances), \ } +#define MLXSW_AFK_BLOCK_HIGH_ENTROPY (_encoding, _instances) \ + { \ + .encoding = _encoding, \ + .instances = _instances, \ + .instances_count = ARRAY_SIZE(_instances), \ + .high_entropy = true, \ + } +struct mlxsw_afk_element_usage { DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX); };
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +6 -6
@@ -334,14 +334,14 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = { };static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = { -MLXSW_AFK_BLOCK (0x10 , mlxsw_sp_afk_element_info_mac_0), -MLXSW_AFK_BLOCK (0x11 , mlxsw_sp_afk_element_info_mac_1), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x10 , mlxsw_sp_afk_element_info_mac_0), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x11 , mlxsw_sp_afk_element_info_mac_1),MLXSW_AFK_BLOCK (0x12 , mlxsw_sp_afk_element_info_mac_2),MLXSW_AFK_BLOCK (0x13 , mlxsw_sp_afk_element_info_mac_3),MLXSW_AFK_BLOCK (0x14 , mlxsw_sp_afk_element_info_mac_4), -MLXSW_AFK_BLOCK (0x1A , mlxsw_sp_afk_element_info_mac_5b), -MLXSW_AFK_BLOCK (0x38 , mlxsw_sp_afk_element_info_ipv4_0), -MLXSW_AFK_BLOCK (0x39 , mlxsw_sp_afk_element_info_ipv4_1), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x1A , mlxsw_sp_afk_element_info_mac_5b), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x38 , mlxsw_sp_afk_element_info_ipv4_0), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x39 , mlxsw_sp_afk_element_info_ipv4_1),MLXSW_AFK_BLOCK (0x3A , mlxsw_sp_afk_element_info_ipv4_2),MLXSW_AFK_BLOCK (0x36 , mlxsw_sp_afk_element_info_ipv4_5b),MLXSW_AFK_BLOCK (0x40 , mlxsw_sp_afk_element_info_ipv6_0),
@@ -350,7 +350,7 @@ static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = {MLXSW_AFK_BLOCK (0x43 , mlxsw_sp_afk_element_info_ipv6_3),MLXSW_AFK_BLOCK (0x44 , mlxsw_sp_afk_element_info_ipv6_4),MLXSW_AFK_BLOCK (0x45 , mlxsw_sp_afk_element_info_ipv6_5), -MLXSW_AFK_BLOCK (0x90 , mlxsw_sp_afk_element_info_l4_0), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x90 , mlxsw_sp_afk_element_info_l4_0), MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2), };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 58/356 mlxsw: spectrum_acl_flex_keys: Constify struct mlxsw_afk_element_inst
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit bec2a32145d5cc066df29182fa0e5b0d4329b1a1 ]
'struct mlxsw_afk_element_inst' are not modified in these drivers.
Constifying these structures moves some data to a read-only section, so increases overall security.
Update a few functions and struct mlxsw_afk_block accordingly.
On a x86_64, with allmodconfig, as an example:
Before:
======
text data bss dec hex filename
4278 4032 0 8310 2076 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.o
After:
=====
text data bss dec hex filename
7934 352 0 8286 205e drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.o
Stable-dep-of: 217bbf156f93 ("mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4")
--- .../mellanox/mlxsw/core_acl_flex_keys.c | 6 +- .../mellanox/mlxsw/core_acl_flex_keys.h | 2 +- .../mellanox/mlxsw/spectrum_acl_flex_keys.c | 66 +++++++++---------- 3 files changed, 37 insertions(+), 37 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +3 -3
@@ -67,7 +67,7 @@ static bool mlxsw_afk_blocks_check(struct mlxsw_afk *mlxsw_afk)for (j =0 ; j < block->instances_count; j++) {const struct mlxsw_afk_element_info *elinfo; -struct mlxsw_afk_element_inst *elinst; +const struct mlxsw_afk_element_inst *elinst; elinst = &block->instances[j]; elinfo = &mlxsw_afk_element_infos[elinst->element];
@@ -153,7 +153,7 @@ static void mlxsw_afk_picker_count_hits(struct mlxsw_afk *mlxsw_afk,const struct mlxsw_afk_block *block = &mlxsw_afk->blocks[i];for (j =0 ; j < block->instances_count; j++) { -struct mlxsw_afk_element_inst *elinst; +const struct mlxsw_afk_element_inst *elinst; elinst = &block->instances[j];if (elinst->element == element) {
@@ -336,7 +336,7 @@ mlxsw_afk_block_elinst_get(const struct mlxsw_afk_block *block,int i;for (i =0 ; i < block->instances_count; i++) { -struct mlxsw_afk_element_inst *elinst; +const struct mlxsw_afk_element_inst *elinst; elinst = &block->instances[i];if (elinst->element == element)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +1 -1
@@ -117,7 +117,7 @@ struct mlxsw_afk_element_inst { /* element instance in actual block */struct mlxsw_afk_block {u16 encoding;/* block ID */ -struct mlxsw_afk_element_inst *instances; +const struct mlxsw_afk_element_inst *instances;unsigned int instances_count;bool high_entropy; };
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +33 -33
215 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 59/356 mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit 217bbf156f93ada86b91617489e7ba8a0904233c ]
The driver is currently using an ACL key block that is not supported by Spectrum-4. This works because the driver is only using a single field from this key block which is located in the same offset in the equivalent Spectrum-4 key block.
The issue was discovered when the firmware started rejecting the use of the unsupported key block. The change has been reverted to avoid breaking users that only update their firmware.
Nonetheless, fix the issue by using the correct key block.
--- .../net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +5 -1
@@ -324,6 +324,10 @@ static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */ }; +static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1b[] = { +MLXSW_AFK_ELEMENT_INST_BUF (SRC_IP_0_31 ,0x04 ,4 ), +}; +static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = {MLXSW_AFK_ELEMENT_INST_U32 (VIRT_ROUTER ,0x04 ,20 ,12 ), };
@@ -341,7 +345,7 @@ static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = {MLXSW_AFK_BLOCK (0x14 , mlxsw_sp_afk_element_info_mac_4),MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x1A , mlxsw_sp_afk_element_info_mac_5b),MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x38 , mlxsw_sp_afk_element_info_ipv4_0), -MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x39 , mlxsw_sp_afk_element_info_ipv4_1), +MLXSW_AFK_BLOCK_HIGH_ENTROPY (0x3F , mlxsw_sp_afk_element_info_ipv4_1b),MLXSW_AFK_BLOCK (0x3A , mlxsw_sp_afk_element_info_ipv4_2),MLXSW_AFK_BLOCK (0x36 , mlxsw_sp_afk_element_info_ipv4_5b), MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 60/356 geneve: do not assume mac header is set in geneve_xmit_skb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 8588c99c7d47448fcae39e3227d6e2bb97aad86d ]
We should not assume mac header is set in output path.
Use skb_eth_hdr() instead of eth_hdr() to fix the issue.
sysbot reported the following :
WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 skb_mac_header include/linux/skbuff.h:3052 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 eth_hdr include/linux/if_ether.h:24 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit_skb drivers/net/geneve.c:898 [inline] WARNING: CPU: 0 PID: 11635 at include/linux/skbuff.h:3052 geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039 Modules linked in: CPU: 0 UID: 0 PID: 11635 Comm: syz.4.1423 Not tainted 6.12.0-syzkaller-10296-gaaf20f870da0 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 RIP: 0010:skb_mac_header include/linux/skbuff.h:3052 [inline] RIP: 0010:eth_hdr include/linux/if_ether.h:24 [inline] RIP: 0010:geneve_xmit_skb drivers/net/geneve.c:898 [inline] RIP: 0010:geneve_xmit+0x4c38/0x5730 drivers/net/geneve.c:1039 Code: 21 c6 02 e9 35 d4 ff ff e8 a5 48 4c fb 90 0f 0b 90 e9 fd f5 ff ff e8 97 48 4c fb 90 0f 0b 90 e9 d8 f5 ff ff e8 89 48 4c fb 90 <0f> 0b 90 e9 41 e4 ff ff e8 7b 48 4c fb 90 0f 0b 90 e9 cd e7 ff ff RSP: 0018:ffffc90003b2f870 EFLAGS: 00010283 RAX: 000000000000037a RBX: 000000000000ffff RCX: ffffc9000dc3d000 RDX: 0000000000080000 RSI: ffffffff86428417 RDI: 0000000000000003 RBP: ffffc90003b2f9f0 R08: 0000000000000003 R09: 000000000000ffff R10: 000000000000ffff R11: 0000000000000002 R12: ffff88806603c000 R13: 0000000000000000 R14: ffff8880685b2780 R15: 0000000000000e23 FS: 00007fdc2deed6c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b30a1dff8 CR3: 0000000056b8c000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> __netdev_start_xmit include/linux/netdevice.h:5002 [inline] netdev_start_xmit include/linux/netdevice.h:5011 [inline] __dev_direct_xmit+0x58a/0x720 net/core/dev.c:4490 dev_direct_xmit include/linux/netdevice.h:3181 [inline] packet_xmit+0x1e4/0x360 net/packet/af_packet.c:285 packet_snd net/packet/af_packet.c:3146 [inline] packet_sendmsg+0x2700/0x5660 net/packet/af_packet.c:3178 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg net/socket.c:726 [inline] __sys_sendto+0x488/0x4f0 net/socket.c:2197 __do_sys_sendto net/socket.c:2204 [inline] __se_sys_sendto net/socket.c:2200 [inline] __x64_sys_sendto+0xe0/0x1c0 net/socket.c:2200 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
--- drivers/net/geneve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/geneve.c +1 -1
@@ -986,7 +986,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,if (geneve->cfg.df ==GENEVE_DF_SET ) { df =htons (IP_DF ); }else if (geneve->cfg.df ==GENEVE_DF_INHERIT ) { -struct ethhdr *eth =eth_hdr (skb); +struct ethhdr *eth =skb_eth_hdr (skb);if (ntohs (eth->h_proto) ==ETH_P_IPV6 ) { df =htons (IP_DF );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 61/356 net/mlx5e: Remove workaround to avoid syndrome for internal port
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <[email protected]>
[ Upstream commit 5085f861b414e4a51ce28a891dfa32a10a54b64e ]
Previously a workaround was added to avoid syndrome 0xcdb051. It is triggered when offload a rule with tunnel encapsulation, and forwarding to another table, but not matching on the internal port in firmware steering mode. The original workaround skips internal tunnel port logic, which is not correct as not all cases are considered. As an example, if vlan is configured on the uplink port, traffic can't pass because vlan header is not added with this workaround. Besides, there is no such issue for software steering. So, this patch removes that, and returns error directly if trying to offload such rule for firmware steering.
--- .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +11 -2
@@ -5,6 +5,7 @@#include <net/nexthop.h> #include <net/ip_tunnels.h> #include "tc_tun_encap.h" +#include "fs_core.h" #include "en_tc.h" #include "tc_tun.h" #include "rep/tc.h"
@@ -24,10 +25,18 @@ static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv, route_dev =dev_get_by_index (dev_net (e->out_dev), e->route_dev_ifindex); -if (!route_dev || !netif_is_ovs_master (route_dev) || - attr->parse_attr->filter_dev == e->out_dev) +if (!route_dev || !netif_is_ovs_master (route_dev)) goto out; +if (priv->mdev->priv.steering->mode ==MLX5_FLOW_STEERING_MODE_DMFS && +mlx5e_eswitch_uplink_rep (attr->parse_attr->filter_dev) && + (attr->esw_attr->dests[out_index].flags &MLX5_ESW_DEST_ENCAP )) { +mlx5_core_warn (priv->mdev, +"Matching on external port with encap + fwd to table actions is not allowed for firmware steering\n" ); + err = -EINVAL ; + goto out; + } + err =mlx5e_set_fwd_to_int_port_actions (priv, attr, e->route_dev_ifindex,MLX5E_TC_INT_PORT_EGRESS , &attr->action, out_index);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 62/356 net: avoid potential UAF in default_operstate()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 750e51603395e755537da08f745864c93e3ce741 ]
syzbot reported an UAF in default_operstate() [1]
Issue is a race between device and netns dismantles.
After calling __rtnl_unlock() from netdev_run_todo(), we can not assume the netns of each device is still alive.
Make sure the device is not in NETREG_UNREGISTERED state, and add an ASSERT_RTNL() before the call to __dev_get_by_index().
We might move this ASSERT_RTNL() in __dev_get_by_index() in the future.
[1]
BUG: KASAN: slab-use-after-free in __dev_get_by_index+0x5d/0x110 net/core/dev.c:852 Read of size 8 at addr ffff888043eba1b0 by task syz.0.0/5339 CPU: 0 UID: 0 PID: 5339 Comm: syz.0.0 Not tainted 6.12.0-syzkaller-10296-gaaf20f870da0 #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:378 [inline] print_report+0x169/0x550 mm/kasan/report.c:489 kasan_report+0x143/0x180 mm/kasan/report.c:602 __dev_get_by_index+0x5d/0x110 net/core/dev.c:852 default_operstate net/core/link_watch.c:51 [inline] rfc2863_policy+0x224/0x300 net/core/link_watch.c:67 linkwatch_do_dev+0x3e/0x170 net/core/link_watch.c:170 netdev_run_todo+0x461/0x1000 net/core/dev.c:10894 rtnl_unlock net/core/rtnetlink.c:152 [inline] rtnl_net_unlock include/linux/rtnetlink.h:133 [inline] rtnl_dellink+0x760/0x8d0 net/core/rtnetlink.c:3520 rtnetlink_rcv_msg+0x791/0xcf0 net/core/rtnetlink.c:6911 netlink_rcv_skb+0x1e3/0x430 net/netlink/af_netlink.c:2541 netlink_unicast_kernel net/netlink/af_netlink.c:1321 [inline] netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1347 netlink_sendmsg+0x8e4/0xcb0 net/netlink/af_netlink.c:1891 sock_sendmsg_nosec net/socket.c:711 [inline] __sock_sendmsg+0x221/0x270 net/socket.c:726 ____sys_sendmsg+0x52a/0x7e0 net/socket.c:2583 ___sys_sendmsg net/socket.c:2637 [inline] __sys_sendmsg+0x269/0x350 net/socket.c:2669 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f2a3cb80809 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f2a3d9cd058 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007f2a3cd45fa0 RCX: 00007f2a3cb80809 RDX: 0000000000000000 RSI: 0000000020000000 RDI: 0000000000000008 RBP: 00007f2a3cbf393e R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007f2a3cd45fa0 R15: 00007ffd03bc65c8 </TASK> Allocated by task 5339: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __kmalloc_cache_noprof+0x243/0x390 mm/slub.c:4314 kmalloc_noprof include/linux/slab.h:901 [inline] kmalloc_array_noprof include/linux/slab.h:945 [inline] netdev_create_hash net/core/dev.c:11870 [inline] netdev_init+0x10c/0x250 net/core/dev.c:11890 ops_init+0x31e/0x590 net/core/net_namespace.c:138 setup_net+0x287/0x9e0 net/core/net_namespace.c:362 copy_net_ns+0x33f/0x570 net/core/net_namespace.c:500 create_new_namespaces+0x425/0x7b0 kernel/nsproxy.c:110 unshare_nsproxy_namespaces+0x124/0x180 kernel/nsproxy.c:228 ksys_unshare+0x57d/0xa70 kernel/fork.c:3314 __do_sys_unshare kernel/fork.c:3385 [inline] __se_sys_unshare kernel/fork.c:3383 [inline] __x64_sys_unshare+0x38/0x40 kernel/fork.c:3383 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 12: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:582 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x59/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2338 [inline] slab_free mm/slub.c:4598 [inline] kfree+0x196/0x420 mm/slub.c:4746 netdev_exit+0x65/0xd0 net/core/dev.c:11992 ops_exit_list net/core/net_namespace.c:172 [inline] cleanup_net+0x802/0xcc0 net/core/net_namespace.c:632 process_one_work kernel/workqueue.c:3229 [inline] process_scheduled_works+0xa63/0x1850 kernel/workqueue.c:3310 worker_thread+0x870/0xd30 kernel/workqueue.c:3391 kthread+0x2f0/0x390 kernel/kthread.c:389 ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244 The buggy address belongs to the object at ffff888043eba000 which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 432 bytes inside of
freed 2048-byte region [ffff888043eba000, ffff888043eba800)
The buggy address belongs to the physical page: page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x43eb8 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x4fff00000000040(head|node=1|zone=1|lastcpupid=0x7ff) page_type: f5(slab) raw: 04fff00000000040 ffff88801ac42000 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000080008 00000001f5000000 0000000000000000
head: 04fff00000000040 ffff88801ac42000 dead000000000122 0000000000000000
head: 0000000000000000 0000000000080008 00000001f5000000 0000000000000000
head: 04fff00000000003 ffffea00010fae01 ffffffffffffffff 0000000000000000
head: 0000000000000008 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 5339, tgid 5338 (syz.0.0), ts 69674195892, free_ts 69663220888
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1556
prep_new_page mm/page_alloc.c:1564 [inline]
get_page_from_freelist+0x3649/0x3790 mm/page_alloc.c:3474
__alloc_pages_noprof+0x292/0x710 mm/page_alloc.c:4751
alloc_pages_mpol_noprof+0x3e8/0x680 mm/mempolicy.c:2265
alloc_slab_page+0x6a/0x140 mm/slub.c:2408
allocate_slab+0x5a/0x2f0 mm/slub.c:2574
new_slab mm/slub.c:2627 [inline]
___slab_alloc+0xcd1/0x14b0 mm/slub.c:3815
__slab_alloc+0x58/0xa0 mm/slub.c:3905
__slab_alloc_node mm/slub.c:3980 [inline]
slab_alloc_node mm/slub.c:4141 [inline]
__do_kmalloc_node mm/slub.c:4282 [inline]
__kmalloc_noprof+0x2e6/0x4c0 mm/slub.c:4295
kmalloc_noprof include/linux/slab.h:905 [inline]
sk_prot_alloc+0xe0/0x210 net/core/sock.c:2165
sk_alloc+0x38/0x370 net/core/sock.c:2218
__netlink_create+0x65/0x260 net/netlink/af_netlink.c:629
__netlink_kernel_create+0x174/0x6f0 net/netlink/af_netlink.c:2015
netlink_kernel_create include/linux/netlink.h:62 [inline]
uevent_net_init+0xed/0x2d0 lib/kobject_uevent.c:783
ops_init+0x31e/0x590 net/core/net_namespace.c:138
setup_net+0x287/0x9e0 net/core/net_namespace.c:362
page last free pid 1032 tgid 1032 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1127 [inline]
free_unref_page+0xdf9/0x1140 mm/page_alloc.c:2657
__slab_free+0x31b/0x3d0 mm/slub.c:4509
qlink_free mm/kasan/quarantine.c:163 [inline]
qlist_free_all+0x9a/0x140 mm/kasan/quarantine.c:179
kasan_quarantine_reduce+0x14f/0x170 mm/kasan/quarantine.c:286
__kasan_slab_alloc+0x23/0x80 mm/kasan/common.c:329
kasan_slab_alloc include/linux/kasan.h:250 [inline]
slab_post_alloc_hook mm/slub.c:4104 [inline]
slab_alloc_node mm/slub.c:4153 [inline]
kmem_cache_alloc_node_noprof+0x1d9/0x380 mm/slub.c:4205
__alloc_skb+0x1c3/0x440 net/core/skbuff.c:668
alloc_skb include/linux/skbuff.h:1323 [inline]
alloc_skb_with_frags+0xc3/0x820 net/core/skbuff.c:6612
sock_alloc_send_pskb+0x91a/0xa60 net/core/sock.c:2881
sock_alloc_send_skb include/net/sock.h:1797 [inline]
mld_newpack+0x1c3/0xaf0 net/ipv6/mcast.c:1747
add_grhead net/ipv6/mcast.c:1850 [inline]
add_grec+0x1492/0x19a0 net/ipv6/mcast.c:1988
mld_send_initial_cr+0x228/0x4b0 net/ipv6/mcast.c:2234
ipv6_mc_dad_complete+0x88/0x490 net/ipv6/mcast.c:2245
addrconf_dad_completed+0x712/0xcd0 net/ipv6/addrconf.c:4342
addrconf_dad_work+0xdc2/0x16f0
process_one_work kernel/workqueue.c:3229 [inline]
process_scheduled_works+0xa63/0x1850 kernel/workqueue.c:3310
Memory state around the buggy address:
ffff888043eba080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888043eba100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff888043eba180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888043eba200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888043eba280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb--- net/core/link_watch.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/core/link_watch.c +6 -1
@@ -45,9 +45,14 @@ static unsigned char default_operstate(const struct net_device *dev)int iflink =dev_get_iflink (dev);struct net_device *peer; -if (iflink == dev->ifindex) +/* If called from netdev_run_todo()/linkwatch_sync_dev(), +* dev_net(dev) can be already freed, and RTNL is not held. +*/ +if (dev->reg_state ==NETREG_UNREGISTERED || + iflink == dev->ifindex)return IF_OPER_DOWN ; +ASSERT_RTNL (); peer =__dev_get_by_index (dev_net (dev), iflink);if (!peer)return IF_OPER_DOWN ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 63/356 KVM: arm64: Change kvm_handle_mmio_return() return polarity
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <[email protected]>
[ Upstream commit cc81b6dfc3bc82c3a2600eefbd3823bdb2190197 ]
Most exit handlers return <= 0 to indicate that the host needs to handle the exit. Make kvm_handle_mmio_return() consistent with the exit handlers in handle_exit(). This makes the code easier to reason about, and makes it easier to add other handlers in future patches.
No functional change intended.
Stable-dep-of: e735a5da6442 ("KVM: arm64: Don't retire aborted MMIO instruction")
--- arch/arm64/kvm/arm.c | 2 +- arch/arm64/kvm/mmio.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm64/kvm/arm.c +1 -1
@@ -900,7 +900,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)if (run->exit_reason ==KVM_EXIT_MMIO ) { ret =kvm_handle_mmio_return (vcpu); -if (ret) +if (ret <=0 )return ret; }
arch/arm64/kvm/mmio.c +2 -2
@@ -86,7 +86,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)/* Detect an already handled MMIO return */ if (unlikely (!vcpu->mmio_needed)) -return 0 ; +return 1 ; vcpu->mmio_needed =0 ;
@@ -117,7 +117,7 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)*/ kvm_incr_pc (vcpu); -return 0 ; +return 1 ; }int io_mem_abort (struct kvm_vcpu *vcpu,phys_addr_t fault_ipa)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 64/356 KVM: arm64: Dont retire aborted MMIO instruction
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Upton <[email protected]>
[ Upstream commit e735a5da64420a86be370b216c269b5dd8e830e2 ]
Returning an abort to the guest for an unsupported MMIO access is a documented feature of the KVM UAPI. Nevertheless, it's clear that this plumbing has seen limited testing, since userspace can trivially cause a WARN in the MMIO return:
WARNING: CPU: 0 PID: 30558 at arch/arm64/include/asm/kvm_emulate.h:536 kvm_handle_mmio_return+0x46c/0x5c4 arch/arm64/include/asm/kvm_emulate.h:536 Call trace: kvm_handle_mmio_return+0x46c/0x5c4 arch/arm64/include/asm/kvm_emulate.h:536 kvm_arch_vcpu_ioctl_run+0x98/0x15b4 arch/arm64/kvm/arm.c:1133 kvm_vcpu_ioctl+0x75c/0xa78 virt/kvm/kvm_main.c:4487 __do_sys_ioctl fs/ioctl.c:51 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __arm64_sys_ioctl+0x14c/0x1c8 fs/ioctl.c:893 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x1e0/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x38/0x68 arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x90/0xfc arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x190/0x194 arch/arm64/kernel/entry.S:598
The splat is complaining that KVM is advancing PC while an exception is pending, i.e. that KVM is retiring the MMIO instruction despite a pending synchronous external abort. Womp womp.
Fix the glaring UAPI bug by skipping over all the MMIO emulation in case there is a pending synchronous exception. Note that while userspace is capable of pending an asynchronous exception (SError, IRQ, or FIQ), it is still safe to retire the MMIO instruction in this case as (1) they are by definition asynchronous, and (2) KVM relies on hardware support for pending/delivering these exceptions instead of the software state machine for advancing PC.
--- arch/arm64/kvm/mmio.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
arch/arm64/kvm/mmio.c +30 -2
@@ -72,6 +72,31 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len)return data; } +static bool kvm_pending_sync_exception (struct kvm_vcpu *vcpu) +{ +if (!vcpu_get_flag (vcpu,PENDING_EXCEPTION )) +return false; + +if (vcpu_el1_is_32bit (vcpu)) { +switch (vcpu_get_flag (vcpu,EXCEPT_MASK )) { +case unpack_vcpu_flag (EXCEPT_AA32_UND ): +case unpack_vcpu_flag (EXCEPT_AA32_IABT ): +case unpack_vcpu_flag (EXCEPT_AA32_DABT ): +return true; +default : +return false; + } + }else { +switch (vcpu_get_flag (vcpu,EXCEPT_MASK )) { +case unpack_vcpu_flag (EXCEPT_AA64_EL1_SYNC ): +case unpack_vcpu_flag (EXCEPT_AA64_EL2_SYNC ): +return true; +default : +return false; + } + } +} +/** * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation * or in-kernel IO emulation
@@ -84,8 +109,11 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu)unsigned int len;int mask; -/* Detect an already handled MMIO return */ -if (unlikely (!vcpu->mmio_needed)) +/* +* Detect if the MMIO return was already handled or if userspace aborted +* the MMIO access. +*/ +if (unlikely (!vcpu->mmio_needed ||kvm_pending_sync_exception (vcpu)))return 1 ; vcpu->mmio_needed =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 65/356 xhci: Allow RPM on the USB controller (1022:43f7) by default
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Basavaraj Natikar <[email protected]>
[ Upstream commit 28cbed496059fe1868203b76e9e0ef285733524d ]
Enable runtime PM by default for older AMD 1022:43f7 xHCI 1.1 host as it is proven to work.
Driver enables runtime PM by default for newer xHCI 1.2 host.
Stable-dep-of: d7b11fe57902 ("xhci: Combine two if statements for Etron xHCI host")
--- drivers/usb/host/xhci-pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/usb/host/xhci-pci.c +4 -1
@@ -374,8 +374,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_RESET_ON_RESUME ; } -if (pdev->vendor ==PCI_VENDOR_ID_AMD ) +if (pdev->vendor ==PCI_VENDOR_ID_AMD ) { xhci->quirks |=XHCI_TRUST_TX_LENGTH ; +if (pdev->device ==0x43f7 ) + xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ; + } if ((pdev->vendor == PCI_VENDOR_ID_AMD) && ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 66/356 xhci: remove XHCI_TRUST_TX_LENGTH quirk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
[ Upstream commit 34b67198244f2d7d8409fa4eb76204c409c0c97e ]
If this quirk was set then driver would treat transfer events with 'Success' completion code as 'Short packet' if there were untransferred bytes left.
This is so common that turn it into default behavior.
xhci_warn_ratelimited() is no longer used after this, so remove it.
A success event with untransferred bytes left doesn't always mean a misbehaving controller. If there was an error mid a multi-TRB TD it's allowed to issue a success event for the last TRB in that TD.
See xhci 1.2 spec 4.9.1 Transfer Descriptors
"Note: If an error is detected while processing a multi-TRB TD, the xHC
shall generate a Transfer Event for the TRB that the error was detected on with the appropriate error Condition Code, then may advance to the next TD. If in the process of advancing to the next TD, a Transfer TRB is encountered with its IOC flag set, then the Condition Code of the Transfer Event generated for that Transfer TRB should be Success, because there was no error actually associated with the TRB that generated the Event. However, an xHC implementation may redundantly assert the original error Condition Code."
Stable-dep-of: d7b11fe57902 ("xhci: Combine two if statements for Etron xHCI host")
--- drivers/usb/host/xhci-pci.c | 15 ++------------- drivers/usb/host/xhci-rcar.c | 6 ++---- drivers/usb/host/xhci-ring.c | 15 +++++---------- drivers/usb/host/xhci.h | 4 +--- 4 files changed, 10 insertions(+), 30 deletions(-)
drivers/usb/host/xhci-pci.c +2 -13
@@ -337,17 +337,12 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)"QUIRK: Fresco Logic revision %u " "has broken MSI implementation" , pdev->revision); - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; }if (pdev->vendor ==PCI_VENDOR_ID_FRESCO_LOGIC && pdev->device ==PCI_DEVICE_ID_FRESCO_LOGIC_FL1009 ) xhci->quirks |=XHCI_BROKEN_STREAMS ; -if (pdev->vendor ==PCI_VENDOR_ID_FRESCO_LOGIC && - pdev->device ==PCI_DEVICE_ID_FRESCO_LOGIC_FL1100 ) - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; -if (pdev->vendor ==PCI_VENDOR_ID_NEC ) xhci->quirks |=XHCI_NEC_HOST ;
@@ -374,11 +369,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_RESET_ON_RESUME ; } -if (pdev->vendor ==PCI_VENDOR_ID_AMD ) { - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; -if (pdev->device ==0x43f7 ) - xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ; - } +if (pdev->vendor ==PCI_VENDOR_ID_AMD && pdev->device ==0x43f7 ) + xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ; if ((pdev->vendor == PCI_VENDOR_ID_AMD) && ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) ||
@@ -466,7 +458,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)if (pdev->vendor ==PCI_VENDOR_ID_ETRON && pdev->device ==PCI_DEVICE_ID_EJ168 ) { xhci->quirks |=XHCI_RESET_ON_RESUME ; - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; xhci->quirks |=XHCI_BROKEN_STREAMS ; } if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
@@ -477,7 +468,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)if (pdev->vendor ==PCI_VENDOR_ID_RENESAS && pdev->device ==0x0014 ) { - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; xhci->quirks |=XHCI_ZERO_64B_REGS ; } if (pdev->vendor == PCI_VENDOR_ID_RENESAS &&
@@ -507,7 +497,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) }if (pdev->vendor ==PCI_VENDOR_ID_ASMEDIA && pdev->device ==PCI_DEVICE_ID_ASMEDIA_1042A_XHCI ) { - xhci->quirks |=XHCI_TRUST_TX_LENGTH ; xhci->quirks |=XHCI_NO_64BIT_SUPPORT ; } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
drivers/usb/host/xhci-rcar.c +2 -4
@@ -214,8 +214,7 @@ static int xhci_rcar_resume_quirk(struct usb_hcd *hcd)*/ #define SET_XHCI_PLAT_PRIV_FOR_RCAR (firmware) \ .firmware_name = firmware, \ - .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_TRUST_TX_LENGTH | \ - XHCI_SLOW_SUSPEND, \ + .quirks = XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND, \ .init_quirk = xhci_rcar_init_quirk, \ .plat_start = xhci_rcar_start, \ .resume_quirk = xhci_rcar_resume_quirk,
@@ -229,8 +228,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { };static const struct xhci_plat_priv xhci_plat_renesas_rzv2m = { - .quirks =XHCI_NO_64BIT_SUPPORT |XHCI_TRUST_TX_LENGTH | -XHCI_SLOW_SUSPEND , + .quirks =XHCI_NO_64BIT_SUPPORT |XHCI_SLOW_SUSPEND , .init_quirk = xhci_rzv2m_init_quirk, .plat_start = xhci_rzv2m_start, };
drivers/usb/host/xhci-ring.c +5 -10
@@ -2443,8 +2443,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,break ;if (remaining) { frame->status = short_framestatus; -if (xhci->quirks &XHCI_TRUST_TX_LENGTH ) - sum_trbs_for_length = true; + sum_trbs_for_length = true;break ; } frame->status =0 ;
@@ -2693,15 +2692,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,* transfer type */ case COMP_SUCCESS : -if (EVENT_TRB_LEN (le32_to_cpu (event->transfer_len)) ==0 ) -break ; -if (xhci->quirks &XHCI_TRUST_TX_LENGTH || - ep_ring->last_td_was_short) +if (EVENT_TRB_LEN (le32_to_cpu (event->transfer_len)) !=0 ) { trb_comp_code =COMP_SHORT_PACKET ; -else -xhci_warn_ratelimited (xhci, -"WARN Successful completion on short TX for slot %u ep %u: needs XHCI_TRUST_TX_LENGTH quirk?\n" , - slot_id, ep_index); +xhci_dbg (xhci,"Successful completion on short TX for slot %u ep %u with last td short %d\n" , + slot_id, ep_index, ep_ring->last_td_was_short); + }break ;case COMP_SHORT_PACKET :break ;
drivers/usb/host/xhci.h +1 -3
@@ -1619,7 +1619,7 @@ struct xhci_hcd {#define XHCI_RESET_ON_RESUME BIT_ULL(7)#define XHCI_SW_BW_CHECKING BIT_ULL(8)#define XHCI_AMD_0x96_HOST BIT_ULL(9) -#define XHCI_TRUST_TX_LENGTH BIT_ULL(10) +#define XHCI_TRUST_TX_LENGTH BIT_ULL(10)/* Deprecated */ #define XHCI_LPM_SUPPORT BIT_ULL(11)#define XHCI_INTEL_HOST BIT_ULL(12)#define XHCI_SPURIOUS_REBOOT BIT_ULL(13)
@@ -1761,8 +1761,6 @@ static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci) dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) #define xhci_warn(xhci, fmt, args...) \ dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) -#define xhci_warn_ratelimited(xhci, fmt, args...) \ - dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) #define xhci_info(xhci, fmt, args...) \ dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 67/356 xhci: Combine two if statements for Etron xHCI host
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuangyi Chiang <[email protected]>
[ Upstream commit d7b11fe5790203fcc0db182249d7bfd945e44ccb ]
Combine two if statements, because these hosts have the same quirk flags applied.
[Mathias: has stable tag because other fixes in series depend on this]
--- drivers/usb/host/xhci-pci.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/usb/host/xhci-pci.c +2 -6
@@ -456,12 +456,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |=XHCI_DEFAULT_PM_RUNTIME_ALLOW ;if (pdev->vendor ==PCI_VENDOR_ID_ETRON && - pdev->device ==PCI_DEVICE_ID_EJ168 ) { - xhci->quirks |=XHCI_RESET_ON_RESUME ; - xhci->quirks |=XHCI_BROKEN_STREAMS ; - } -if (pdev->vendor ==PCI_VENDOR_ID_ETRON && - pdev->device ==PCI_DEVICE_ID_EJ188 ) { + (pdev->device ==PCI_DEVICE_ID_EJ168 || + pdev->device ==PCI_DEVICE_ID_EJ188 )) { xhci->quirks |=XHCI_RESET_ON_RESUME ; xhci->quirks |=XHCI_BROKEN_STREAMS ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 68/356 xhci: Dont issue Reset Device command to Etron xHCI host
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuangyi Chiang <[email protected]>
[ Upstream commit 76d98856b1c6d06ce18f32c20527a4f9d283e660 ]
Sometimes the hub driver does not recognize the USB device connected to the external USB2.0 hub when the system resumes from S4.
After the SetPortFeature(PORT_RESET) request is completed, the hub driver calls the HCD reset_device callback, which will issue a Reset Device command and free all structures associated with endpoints that were disabled.
This happens when the xHCI driver issue a Reset Device command to inform the Etron xHCI host that the USB device associated with a device slot has been reset. Seems that the Etron xHCI host can not perform this command correctly, affecting the USB device.
To work around this, the xHCI driver should obtain a new device slot with reference to commit 651aaf36a7d7 ("usb: xhci: Handle USB transaction error on address command"), which is another way to inform the Etron xHCI host that the USB device has been reset.
Add a new XHCI_ETRON_HOST quirk flag to invoke the workaround in xhci_discover_or_reset_device().
--- drivers/usb/host/xhci-pci.c | 1 + drivers/usb/host/xhci.c | 19 +++++++++++++++++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 21 insertions(+)
drivers/usb/host/xhci-pci.c +1 -0
@@ -458,6 +458,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)if (pdev->vendor ==PCI_VENDOR_ID_ETRON && (pdev->device ==PCI_DEVICE_ID_EJ168 || pdev->device ==PCI_DEVICE_ID_EJ188 )) { + xhci->quirks |=XHCI_ETRON_HOST ; xhci->quirks |=XHCI_RESET_ON_RESUME ; xhci->quirks |=XHCI_BROKEN_STREAMS ; }
drivers/usb/host/xhci.c +19 -0
@@ -3642,6 +3642,8 @@ void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, xhci->num_active_eps); } +static void xhci_free_dev (struct usb_hcd *hcd,struct usb_device *udev); +/* * This submits a Reset Device Command, which will set the device state to 0, * set the device address to 0, and disable all the endpoints except the default
@@ -3712,6 +3714,23 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd, SLOT_STATE_DISABLED)return 0 ; +if (xhci->quirks &XHCI_ETRON_HOST ) { +/* +* Obtaining a new device slot to inform the xHCI host that +* the USB device has been reset. +*/ + ret =xhci_disable_slot (xhci, udev->slot_id); +xhci_free_virt_device (xhci, udev->slot_id); +if (!ret) { + ret =xhci_alloc_dev (hcd, udev); +if (ret ==1 ) + ret =0 ; +else + ret = -EINVAL ; + } +return ret; + } +trace_xhci_discover_or_reset_device (slot_ctx);xhci_dbg (xhci,"Resetting device with slot ID %u\n" , slot_id);
drivers/usb/host/xhci.h +1 -0
@@ -1660,6 +1660,7 @@ struct xhci_hcd {#define XHCI_ZHAOXIN_HOST BIT_ULL(46)#define XHCI_WRITE_64_HI_LO BIT_ULL(47)#define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48) +#define XHCI_ETRON_HOST BIT_ULL(49)unsigned int num_active_eps;unsigned int limit_active_eps;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 69/356 xhci: Fix control transfer error on Etron xHCI host
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuangyi Chiang <[email protected]>
[ Upstream commit 5e1c67abc9301d05130b7e267c204e7005503b33 ]
Performing a stability stress test on a USB3.0 2.5G ethernet adapter results in errors like this:
[ 91.441469] r8152 2-3:1.0 eth3: get_registers -71 [ 91.458659] r8152 2-3:1.0 eth3: get_registers -71 [ 91.475911] r8152 2-3:1.0 eth3: get_registers -71 [ 91.493203] r8152 2-3:1.0 eth3: get_registers -71 [ 91.510421] r8152 2-3:1.0 eth3: get_registers -71
The r8152 driver will periodically issue lots of control-IN requests to access the status of ethernet adapter hardware registers during the test.
This happens when the xHCI driver enqueue a control TD (which cross over the Link TRB between two ring segments, as shown) in the endpoint zero's transfer ring. Seems the Etron xHCI host can not perform this TD correctly, causing the USB transfer error occurred, maybe the upper driver retry that control-IN request can solve problem, but not all drivers do this.
| |
-------
| TRB | Setup Stage
-------
| TRB | Link
-------
-------
| TRB | Data Stage
-------
| TRB | Status Stage
-------
| |
To work around this, the xHCI driver should enqueue a No Op TRB if next available TRB is the Link TRB in the ring segment, this can prevent the Setup and Data Stage TRB to be breaked by the Link TRB.
Check if the XHCI_ETRON_HOST quirk flag is set before invoking the workaround in xhci_queue_ctrl_tx().
--- drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/usb/host/xhci-ring.c +14 -0
@@ -3828,6 +3828,20 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,if (!urb->setup_packet)return -EINVAL ; +if ((xhci->quirks &XHCI_ETRON_HOST ) && + urb->dev->speed >=USB_SPEED_SUPER ) { +/* +* If next available TRB is the Link TRB in the ring segment then +* enqueue a No Op TRB, this can prevent the Setup and Data Stage +* TRB to be breaked by the Link TRB. +*/ +if (trb_is_link (ep_ring->enqueue +1 )) { + field =TRB_TYPE (TRB_TR_NOOP ) | ep_ring->cycle_state; +queue_trb (xhci, ep_ring, false,0 ,0 , +TRB_INTR_TARGET (0 ), field); + } + } +/* 1 TRB for setup, 1 for status */ num_trbs =2 ;/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 70/356 gpio: grgpio: use a helper variable to store the address of ofdev->dev
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit d036ae41cebdfae92666024163c109b8fef516fa ]
Instead of dereferencing the platform device pointer repeatedly, just store its address in a helper variable.
Stable-dep-of: 050b23d081da ("gpio: grgpio: Add NULL check in grgpio_probe")
--- drivers/gpio/gpio-grgpio.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/gpio/gpio-grgpio.c +12 -11
@@ -328,6 +328,7 @@ static const struct irq_domain_ops grgpio_irq_domain_ops = {static int grgpio_probe (struct platform_device *ofdev) {struct device_node *np = ofdev->dev.of_node; +struct device *dev = &ofdev->dev;void __iomem *regs;struct gpio_chip *gc;struct grgpio_priv *priv;
@@ -337,7 +338,7 @@ static int grgpio_probe(struct platform_device *ofdev)int size;int i; - priv =devm_kzalloc (&ofdev->dev,sizeof (*priv),GFP_KERNEL ); + priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );if (!priv)return -ENOMEM ;
@@ -346,28 +347,28 @@ static int grgpio_probe(struct platform_device *ofdev)return PTR_ERR (regs); gc = &priv->gc; - err =bgpio_init (gc, &ofdev->dev,4 , regs +GRGPIO_DATA , + err =bgpio_init (gc, dev,4 , regs +GRGPIO_DATA , regs +GRGPIO_OUTPUT ,NULL , regs +GRGPIO_DIR ,NULL ,BGPIOF_BIG_ENDIAN_BYTE_ORDER );if (err) { -dev_err (&ofdev->dev,"bgpio_init() failed\n" ); +dev_err (dev,"bgpio_init() failed\n" );return err; } priv->regs = regs; priv->imask = gc->read_reg (regs +GRGPIO_IMASK ); - priv->dev = &ofdev->dev; + priv->dev = dev; gc->owner =THIS_MODULE ; gc->to_irq = grgpio_to_irq; - gc->label =devm_kasprintf (&ofdev->dev,GFP_KERNEL ,"%pOF" , np); + gc->label =devm_kasprintf (dev,GFP_KERNEL ,"%pOF" , np); gc->base =-1 ; err =of_property_read_u32 (np,"nbits" , &prop);if (err || prop <=0 || prop >GRGPIO_MAX_NGPIO ) { gc->ngpio =GRGPIO_MAX_NGPIO ; -dev_dbg (&ofdev->dev, -"No or invalid nbits property: assume %d\n" , gc->ngpio); +dev_dbg (dev,"No or invalid nbits property: assume %d\n" , + gc->ngpio); }else { gc->ngpio = prop; }
@@ -379,7 +380,7 @@ static int grgpio_probe(struct platform_device *ofdev) irqmap = (s32 *)of_get_property (np,"irqmap" , &size);if (irqmap) {if (size < gc->ngpio) { -dev_err (&ofdev->dev, +dev_err (dev,"irqmap shorter than ngpio (%d < %d)\n" , size, gc->ngpio);return -EINVAL ;
@@ -389,7 +390,7 @@ static int grgpio_probe(struct platform_device *ofdev) &grgpio_irq_domain_ops, priv);if (!priv->domain) { -dev_err (&ofdev->dev,"Could not add irq domain\n" ); +dev_err (dev,"Could not add irq domain\n" );return -EINVAL ; }
@@ -419,13 +420,13 @@ static int grgpio_probe(struct platform_device *ofdev) err =gpiochip_add_data (gc, priv);if (err) { -dev_err (&ofdev->dev,"Could not add gpiochip\n" ); +dev_err (dev,"Could not add gpiochip\n" );if (priv->domain)irq_domain_remove (priv->domain);return err; } -dev_info (&ofdev->dev,"regs=0x%p, base=%d, ngpio=%d, irqs=%s\n" , +dev_info (dev,"regs=0x%p, base=%d, ngpio=%d, irqs=%s\n" , priv->regs, gc->base, gc->ngpio, priv->domain ?"on" :"off" );return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 71/356 gpio: grgpio: Add NULL check in grgpio_probe
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 050b23d081da0f29474de043e9538c1f7a351b3b ]
devm_kasprintf() can return a NULL pointer on failure,but this returned value in grgpio_probe is not checked.
Add NULL check in grgpio_probe, to handle kernel NULL pointer dereference error.
--- drivers/gpio/gpio-grgpio.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpio/gpio-grgpio.c +3 -0
@@ -362,6 +362,9 @@ static int grgpio_probe(struct platform_device *ofdev) gc->owner =THIS_MODULE ; gc->to_irq = grgpio_to_irq; gc->label =devm_kasprintf (dev,GFP_KERNEL ,"%pOF" , np); +if (!gc->label) +return -ENOMEM ; + gc->base =-1 ; err =of_property_read_u32 (np,"nbits" , &prop);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 72/356 serial: amba-pl011: Use port lock wrappers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <[email protected]>
[ Upstream commit 68ca3e72d7463d79d29b6e4961d6028df2a88e25 ]
When a serial port is used for kernel console output, then all modifications to the UART registers which are done from other contexts, e.g. getty, termios, are interference points for the kernel console.
So far this has been ignored and the printk output is based on the principle of hope. The rework of the console infrastructure which aims to support threaded and atomic consoles, requires to mark sections which modify the UART registers as unsafe. This allows the atomic write function to make informed decisions and eventually to restore operational state. It also allows to prevent the regular UART code from modifying UART registers while printk output is in progress.
All modifications of UART registers are guarded by the UART port lock, which provides an obvious synchronization point with the console infrastructure.
To avoid adding this functionality to all UART drivers, wrap the spin_[un]lock*() invocations for uart_port::lock into helper functions which just contain the spin_[un]lock*() invocations for now. In a subsequent step these helpers will gain the console synchronization mechanisms.
Converted with coccinelle. No functional change.
Stable-dep-of: 2bcacc1c87ac ("serial: amba-pl011: Fix RX stall when DMA is used")
--- drivers/tty/serial/amba-pl011.c | 72 ++++++++++++++++----------------- 1 file changed, 36 insertions(+), 36 deletions(-)
drivers/tty/serial/amba-pl011.c +36 -36
@@ -347,9 +347,9 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap) flag =TTY_FRAME ; } -spin_unlock (&uap->port.lock); +uart_port_unlock (&uap->port); sysrq =uart_handle_sysrq_char (&uap->port, ch &255 ); -spin_lock (&uap->port.lock); +uart_port_lock (&uap->port);if (!sysrq)uart_insert_char (&uap->port, ch,UART011_DR_OE , ch, flag);
@@ -544,7 +544,7 @@ static void pl011_dma_tx_callback(void *data)unsigned long flags;u16 dmacr; -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags);if (uap->dmatx.queued)dma_unmap_single (dmatx->chan->device->dev, dmatx->dma, dmatx->len,DMA_TO_DEVICE );
@@ -565,7 +565,7 @@ static void pl011_dma_tx_callback(void *data)if (!(dmacr &UART011_TXDMAE ) ||uart_tx_stopped (&uap->port) ||uart_circ_empty (&uap->port.state->xmit)) { uap->dmatx.queued = false; -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags);return ; }
@@ -576,7 +576,7 @@ static void pl011_dma_tx_callback(void *data)*/ pl011_start_tx_pio (uap); -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags); }/*
@@ -1004,7 +1004,7 @@ static void pl011_dma_rx_callback(void *data)* routine to flush out the secondary DMA buffer while * we immediately trigger the next DMA job. */ -spin_lock_irq (&uap->port.lock); +uart_port_lock_irq (&uap->port);/* * Rx data can be taken by the UART interrupts during * the DMA irq handler. So we check the residue here.
@@ -1020,7 +1020,7 @@ static void pl011_dma_rx_callback(void *data) ret =pl011_dma_rx_trigger_dma (uap);pl011_dma_rx_chars (uap, pending, lastbuf, false); -spin_unlock_irq (&uap->port.lock); +uart_port_unlock_irq (&uap->port);/* * Do this check after we picked the DMA chars so we don't * get some IRQ immediately from RX.
@@ -1086,11 +1086,11 @@ static void pl011_dma_rx_poll(struct timer_list *t)if (jiffies_to_msecs (jiffies - dmarx->last_jiffies) > uap->dmarx.poll_timeout) { -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags);pl011_dma_rx_stop (uap); uap->im |=UART011_RXIM ;pl011_write (uap->im, uap,REG_IMSC ); -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags); uap->dmarx.running = false;dmaengine_terminate_all (rxchan);
@@ -1186,10 +1186,10 @@ static void pl011_dma_shutdown(struct uart_amba_port *uap)while (pl011_read (uap,REG_FR ) & uap->vendor->fr_busy)cpu_relax (); -spin_lock_irq (&uap->port.lock); +uart_port_lock_irq (&uap->port); uap->dmacr &= ~(UART011_DMAONERR |UART011_RXDMAE |UART011_TXDMAE );pl011_write (uap->dmacr, uap,REG_DMACR ); -spin_unlock_irq (&uap->port.lock); +uart_port_unlock_irq (&uap->port);if (uap->using_tx_dma) {/* In theory, this should already be done by pl011_dma_flush_buffer */
@@ -1400,9 +1400,9 @@ static void pl011_throttle_rx(struct uart_port *port) {unsigned long flags; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);pl011_stop_rx (port); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static void pl011_enable_ms (struct uart_port *port)
@@ -1420,7 +1420,7 @@ __acquires(&uap->port.lock) {pl011_fifo_to_tty (uap); -spin_unlock (&uap->port.lock); +uart_port_unlock (&uap->port);tty_flip_buffer_push (&uap->port.state->port);/* * If we were temporarily out of DMA mode for a while,
@@ -1445,7 +1445,7 @@ __acquires(&uap->port.lock)#endif } } -spin_lock (&uap->port.lock); +uart_port_lock (&uap->port); } static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c,
@@ -1551,7 +1551,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id)unsigned int status, pass_counter =AMBA_ISR_PASS_LIMIT ;int handled =0 ; -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags); status =pl011_read (uap,REG_RIS ) & uap->im;if (status) { do {
@@ -1581,7 +1581,7 @@ static irqreturn_t pl011_int(int irq, void *dev_id) handled =1 ; } -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags);return IRQ_RETVAL (handled); }
@@ -1653,14 +1653,14 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)unsigned long flags;unsigned int lcr_h; -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags); lcr_h =pl011_read (uap,REG_LCRH_TX );if (break_state ==-1 ) lcr_h |= UART01x_LCRH_BRK;else lcr_h &= ~UART01x_LCRH_BRK;pl011_write (lcr_h, uap,REG_LCRH_TX ); -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags); }#ifdef CONFIG_CONSOLE_POLL
@@ -1799,7 +1799,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)unsigned long flags;unsigned int i; -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags);/* Clear out any spuriously appearing RX interrupts */ pl011_write (UART011_RTIS |UART011_RXIS , uap,REG_ICR );
@@ -1821,7 +1821,7 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)if (!pl011_dma_rx_running (uap)) uap->im |=UART011_RXIM ;pl011_write (uap->im, uap,REG_IMSC ); -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags); }static void pl011_unthrottle_rx (struct uart_port *port)
@@ -1829,7 +1829,7 @@ static void pl011_unthrottle_rx(struct uart_port *port) struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);unsigned long flags; -spin_lock_irqsave (&uap->port.lock, flags); +uart_port_lock_irqsave (&uap->port, &flags); uap->im =UART011_RTIM ;if (!pl011_dma_rx_running (uap))
@@ -1837,7 +1837,7 @@ static void pl011_unthrottle_rx(struct uart_port *port)pl011_write (uap->im, uap,REG_IMSC ); -spin_unlock_irqrestore (&uap->port.lock, flags); +uart_port_unlock_irqrestore (&uap->port, flags); }static int pl011_startup (struct uart_port *port)
@@ -1857,7 +1857,7 @@ static int pl011_startup(struct uart_port *port)pl011_write (uap->vendor->ifls, uap,REG_IFLS ); -spin_lock_irq (&uap->port.lock); +uart_port_lock_irq (&uap->port); cr =pl011_read (uap,REG_CR ); cr &=UART011_CR_RTS |UART011_CR_DTR ;
@@ -1868,7 +1868,7 @@ static int pl011_startup(struct uart_port *port)pl011_write (cr, uap,REG_CR ); -spin_unlock_irq (&uap->port.lock); +uart_port_unlock_irq (&uap->port);/* * initialise the old status of the modem signals
@@ -1929,12 +1929,12 @@ static void pl011_disable_uart(struct uart_amba_port *uap)unsigned int cr; uap->port.status &= ~(UPSTAT_AUTOCTS |UPSTAT_AUTORTS ); -spin_lock_irq (&uap->port.lock); +uart_port_lock_irq (&uap->port); cr =pl011_read (uap,REG_CR ); cr &=UART011_CR_RTS |UART011_CR_DTR ; cr |= UART01x_CR_UARTEN |UART011_CR_TXE ;pl011_write (cr, uap,REG_CR ); -spin_unlock_irq (&uap->port.lock); +uart_port_unlock_irq (&uap->port);/* * disable break condition and fifos
@@ -1946,14 +1946,14 @@ static void pl011_disable_uart(struct uart_amba_port *uap)static void pl011_disable_interrupts (struct uart_amba_port *uap) { -spin_lock_irq (&uap->port.lock); +uart_port_lock_irq (&uap->port);/* mask all interrupts and clear all pending ones */ uap->im =0 ;pl011_write (uap->im, uap,REG_IMSC );pl011_write (0xffff , uap,REG_ICR ); -spin_unlock_irq (&uap->port.lock); +uart_port_unlock_irq (&uap->port); }static void pl011_shutdown (struct uart_port *port)
@@ -2098,7 +2098,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, bits =tty_get_frame_size (termios->c_cflag); -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);/* * Update the per-port timeout.
@@ -2172,7 +2172,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, old_cr |=UART011_CR_RXE ;pl011_write (old_cr, uap,REG_CR ); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); } static void
@@ -2190,10 +2190,10 @@ sbsa_uart_set_termios(struct uart_port *port, struct ktermios *termios, termios->c_cflag &= ~(CMSPAR |CRTSCTS ); termios->c_cflag |=CS8 |CLOCAL ; -spin_lock_irqsave (&port->lock, flags); +uart_port_lock_irqsave (port, &flags);uart_update_timeout (port,CS8 , uap->fixed_baud);pl011_setup_status_masks (port, termios); -spin_unlock_irqrestore (&port->lock, flags); +uart_port_unlock_irqrestore (port, flags); }static const char *pl011_type (struct uart_port *port)
@@ -2332,9 +2332,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)if (uap->port.sysrq) locked =0 ;else if (oops_in_progress) - locked =spin_trylock (&uap->port.lock); + locked =uart_port_trylock (&uap->port);else -spin_lock (&uap->port.lock); +uart_port_lock (&uap->port);/* * First save the CR then disable the interrupts
@@ -2360,7 +2360,7 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)pl011_write (old_cr, uap,REG_CR );if (locked) -spin_unlock (&uap->port.lock); +uart_port_unlock (&uap->port);local_irq_restore (flags);clk_disable (uap->clk);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 73/356 serial: amba-pl011: Fix RX stall when DMA is used
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kartik Rajput <[email protected]>
[ Upstream commit 2bcacc1c87acf9a8ebc17de18cb2b3cfeca547cf ]
Function pl011_throttle_rx() calls pl011_stop_rx() to disable RX, which also disables the RX DMA by clearing the RXDMAE bit of the DMACR register. However, to properly unthrottle RX when DMA is used, the function pl011_unthrottle_rx() is expected to set the RXDMAE bit of the DMACR register, which it currently lacks. This causes RX to stall after the throttle API is called.
Set RXDMAE bit in the DMACR register while unthrottling RX if RX DMA is used.
--- drivers/tty/serial/amba-pl011.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/tty/serial/amba-pl011.c +5 -0
@@ -1837,6 +1837,11 @@ static void pl011_unthrottle_rx(struct uart_port *port)pl011_write (uap->im, uap,REG_IMSC ); +if (uap->using_rx_dma) { + uap->dmacr |=UART011_RXDMAE ; +pl011_write (uap->dmacr, uap,REG_DMACR ); + } +uart_port_unlock_irqrestore (&uap->port, flags); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 74/356 soc/fsl: cpm: qmc: Convert to platform remove callback returning void
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 14914a115e807aa2f8025e451133627a64120ac3 ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: cb3daa51db81 ("soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure")
--- drivers/soc/fsl/qe/qmc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/soc/fsl/qe/qmc.c +2 -4
@@ -1414,7 +1414,7 @@ static int qmc_probe(struct platform_device *pdev)return ret; } -static int qmc_remove (struct platform_device *pdev) +static void qmc_remove (struct platform_device *pdev) {struct qmc *qmc =platform_get_drvdata (pdev);
@@ -1426,8 +1426,6 @@ static int qmc_remove(struct platform_device *pdev)/* Disconnect the serial from TSA */ tsa_serial_disconnect (qmc->tsa_serial); - -return 0 ; }static const struct of_device_id qmc_id_table[] = {
@@ -1442,7 +1440,7 @@ static struct platform_driver qmc_driver = { .of_match_table = of_match_ptr(qmc_id_table), }, .probe = qmc_probe, - .remove = qmc_remove, + .remove_new = qmc_remove, };module_platform_driver (qmc_driver);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 75/356 soc: fsl: cpm1: qmc: Fix blank line and spaces
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herve Codina <[email protected]>
[ Upstream commit f06ab938bcddcb3c3a0b458b03a827c701919c9e ]
checkpatch.pl raises the following issues
CHECK: Please don't use multiple blank lines
CHECK: Alignment should match open parenthesis
Fix them.
Stable-dep-of: cb3daa51db81 ("soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure")
--- drivers/soc/fsl/qe/qmc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/soc/fsl/qe/qmc.c +4 -6
@@ -253,7 +253,6 @@ static inline void qmc_setbits32(void __iomem *addr, u32 set)qmc_write32 (addr,qmc_read32 (addr) | set); } -int qmc_chan_get_info (struct qmc_chan *chan,struct qmc_chan_info *info) {struct tsa_serial_info tsa_info;
@@ -1093,7 +1092,7 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan)qmc_write32 (chan->s_param +QMC_SPE_ZDSTATE ,0x00000080 );qmc_write16 (chan->s_param +QMC_SPE_MFLR ,60 );qmc_write16 (chan->s_param +QMC_SPE_CHAMR , -QMC_SPE_CHAMR_MODE_HDLC |QMC_SPE_CHAMR_HDLC_IDLM ); +QMC_SPE_CHAMR_MODE_HDLC |QMC_SPE_CHAMR_HDLC_IDLM ); }/* Do not enable interrupts now. They will be enabled later */
@@ -1286,7 +1285,6 @@ static int qmc_probe(struct platform_device *pdev)if (IS_ERR (qmc->scc_regs))return PTR_ERR (qmc->scc_regs); - res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"scc_pram" );if (!res)return -EINVAL ;
@@ -1332,7 +1330,7 @@ static int qmc_probe(struct platform_device *pdev)*/ qmc->bd_size = (nb_chans * (QMC_NB_TXBDS +QMC_NB_RXBDS )) *sizeof (cbd_t); qmc->bd_table =dmam_alloc_coherent (qmc->dev, qmc->bd_size, - &qmc->bd_dma_addr,GFP_KERNEL ); + &qmc->bd_dma_addr,GFP_KERNEL );if (!qmc->bd_table) {dev_err (qmc->dev,"Failed to allocate bd table\n" ); ret = -ENOMEM ;
@@ -1345,7 +1343,7 @@ static int qmc_probe(struct platform_device *pdev)/* Allocate the interrupt table */ qmc->int_size =QMC_NB_INTS *sizeof (u16); qmc->int_table =dmam_alloc_coherent (qmc->dev, qmc->int_size, - &qmc->int_dma_addr,GFP_KERNEL ); + &qmc->int_dma_addr,GFP_KERNEL );if (!qmc->int_table) {dev_err (qmc->dev,"Failed to allocate interrupt table\n" ); ret = -ENOMEM ;
@@ -1393,7 +1391,7 @@ static int qmc_probe(struct platform_device *pdev)/* Enable interrupts */ qmc_write16 (qmc->scc_regs +SCC_SCCM , -SCC_SCCE_IQOV |SCC_SCCE_GINT |SCC_SCCE_GUN |SCC_SCCE_GOV ); +SCC_SCCE_IQOV |SCC_SCCE_GINT |SCC_SCCE_GUN |SCC_SCCE_GOV ); ret =qmc_finalize_chans (qmc);if (ret <0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 76/356 soc: fsl: cpm1: qmc: Re-order probe() operations
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herve Codina <[email protected]>
[ Upstream commit a13bf605342ea9df492b8159cadaa41862b53e15 ]
Current code handles CPM1 version of QMC. In the QUICC Engine (QE) version, some operations done at probe() need to be done in a different order.
In order to prepare the support for the QE version, changed the sequence of operation done at probe():
- Retrieve the tsa_serial earlier, before initializing resources.
- Group SCC initialisation and do this initialization when it is really needed in the probe() sequence.
Having the QE compatible sequence in the CPM1 version does not lead to any issue and works correctly without any regressions.
Stable-dep-of: cb3daa51db81 ("soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure")
--- drivers/soc/fsl/qe/qmc.c | 54 +++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 28 deletions(-)
drivers/soc/fsl/qe/qmc.c +26 -28
@@ -1281,6 +1281,12 @@ static int qmc_probe(struct platform_device *pdev) qmc->dev = &pdev->dev;INIT_LIST_HEAD (&qmc->chan_head); + qmc->tsa_serial =devm_tsa_serial_get_byphandle (qmc->dev, np,"fsl,tsa-serial" ); +if (IS_ERR (qmc->tsa_serial)) { +return dev_err_probe (qmc->dev,PTR_ERR (qmc->tsa_serial), +"Failed to get TSA serial\n" ); + } + qmc->scc_regs =devm_platform_ioremap_resource_byname (pdev,"scc_regs" );if (IS_ERR (qmc->scc_regs))return PTR_ERR (qmc->scc_regs);
@@ -1297,33 +1303,13 @@ static int qmc_probe(struct platform_device *pdev)if (IS_ERR (qmc->dpram))return PTR_ERR (qmc->dpram); - qmc->tsa_serial =devm_tsa_serial_get_byphandle (qmc->dev, np,"fsl,tsa-serial" ); -if (IS_ERR (qmc->tsa_serial)) { -return dev_err_probe (qmc->dev,PTR_ERR (qmc->tsa_serial), -"Failed to get TSA serial\n" ); - } - -/* Connect the serial (SCC) to TSA */ - ret =tsa_serial_connect (qmc->tsa_serial); -if (ret) { -dev_err (qmc->dev,"Failed to connect TSA serial\n" ); -return ret; - } -/* Parse channels informationss */ ret =qmc_of_parse_chans (qmc, np);if (ret) - goto err_tsa_serial_disconnect; +return ret; nb_chans =qmc_nb_chans (qmc); -/* Init GMSR_H and GMSR_L registers */ -qmc_write32 (qmc->scc_regs +SCC_GSMRH , -SCC_GSMRH_CDS |SCC_GSMRH_CTSS |SCC_GSMRH_CDP |SCC_GSMRH_CTSP ); - -/* enable QMC mode */ -qmc_write32 (qmc->scc_regs +SCC_GSMRL ,SCC_GSMRL_MODE_QMC ); -/* * Allocate the buffer descriptor table * 8 rx and 8 tx descriptors per channel
@@ -1333,8 +1319,7 @@ static int qmc_probe(struct platform_device *pdev) &qmc->bd_dma_addr, GFP_KERNEL);if (!qmc->bd_table) {dev_err (qmc->dev,"Failed to allocate bd table\n" ); - ret = -ENOMEM ; - goto err_tsa_serial_disconnect; +return -ENOMEM ; }memset (qmc->bd_table,0 , qmc->bd_size);
@@ -1346,8 +1331,7 @@ static int qmc_probe(struct platform_device *pdev) &qmc->int_dma_addr, GFP_KERNEL);if (!qmc->int_table) {dev_err (qmc->dev,"Failed to allocate interrupt table\n" ); - ret = -ENOMEM ; - goto err_tsa_serial_disconnect; +return -ENOMEM ; }memset (qmc->int_table,0 , qmc->int_size);
@@ -1366,18 +1350,32 @@ static int qmc_probe(struct platform_device *pdev) ret =qmc_setup_tsa (qmc);if (ret) - goto err_tsa_serial_disconnect; +return ret;qmc_write16 (qmc->scc_pram +QMC_GBL_QMCSTATE ,0x8000 ); ret =qmc_setup_chans (qmc);if (ret) - goto err_tsa_serial_disconnect; +return ret;/* Init interrupts table */ ret =qmc_setup_ints (qmc);if (ret) - goto err_tsa_serial_disconnect; +return ret; + +/* Connect the serial (SCC) to TSA */ + ret =tsa_serial_connect (qmc->tsa_serial); +if (ret) { +dev_err (qmc->dev,"Failed to connect TSA serial\n" ); +return ret; + } + +/* Init GMSR_H and GMSR_L registers */ +qmc_write32 (qmc->scc_regs +SCC_GSMRH , +SCC_GSMRH_CDS |SCC_GSMRH_CTSS |SCC_GSMRH_CDP |SCC_GSMRH_CTSP ); + +/* enable QMC mode */ +qmc_write32 (qmc->scc_regs +SCC_GSMRL ,SCC_GSMRL_MODE_QMC );/* Disable and clear interrupts, set the irq handler */ qmc_write16 (qmc->scc_regs +SCC_SCCM ,0x0000 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 77/356 soc: fsl: cpm1: qmc: Introduce qmc_init_resource() and its CPM1 version
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herve Codina <[email protected]>
[ Upstream commit 727b3ab490a5f5e74fb3f246c9fdfb339d309950 ]
Current code handles the CPM1 version of QMC. Resources initialisations (i.e. retrieving base addresses and offsets of different parts) will be slightly different in the QUICC Engine (QE) version. Indeed, in QE version, some resources need to be allocated and are no more "staticaly" defined.
In order to prepare the support for QE version, introduce qmc_init_resource() to initialize those resources and isolate the CPM1 specific operations in a specific function.
Stable-dep-of: cb3daa51db81 ("soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure")
--- drivers/soc/fsl/qe/qmc.c | 47 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-)
drivers/soc/fsl/qe/qmc.c +31 -16
@@ -1265,11 +1265,38 @@ static irqreturn_t qmc_irq_handler(int irq, void *priv)return IRQ_HANDLED ; } +static int qmc_cpm1_init_resources (struct qmc *qmc,struct platform_device *pdev) +{ +struct resource *res; + + qmc->scc_regs =devm_platform_ioremap_resource_byname (pdev,"scc_regs" ); +if (IS_ERR (qmc->scc_regs)) +return PTR_ERR (qmc->scc_regs); + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"scc_pram" ); +if (!res) +return -EINVAL ; + qmc->scc_pram_offset = res->start -get_immrbase (); + qmc->scc_pram =devm_ioremap_resource (qmc->dev, res); +if (IS_ERR (qmc->scc_pram)) +return PTR_ERR (qmc->scc_pram); + + qmc->dpram =devm_platform_ioremap_resource_byname (pdev,"dpram" ); +if (IS_ERR (qmc->dpram)) +return PTR_ERR (qmc->dpram); + +return 0 ; +} + +static int qmc_init_resources (struct qmc *qmc,struct platform_device *pdev) +{ +return qmc_cpm1_init_resources (qmc, pdev); +} +static int qmc_probe (struct platform_device *pdev) {struct device_node *np = pdev->dev.of_node;unsigned int nb_chans; -struct resource *res;struct qmc *qmc;int irq;int ret;
@@ -1287,21 +1314,9 @@ static int qmc_probe(struct platform_device *pdev) "Failed to get TSA serial\n"); } - qmc->scc_regs =devm_platform_ioremap_resource_byname (pdev,"scc_regs" ); -if (IS_ERR (qmc->scc_regs)) -return PTR_ERR (qmc->scc_regs); - - res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"scc_pram" ); -if (!res) -return -EINVAL ; - qmc->scc_pram_offset = res->start -get_immrbase (); - qmc->scc_pram =devm_ioremap_resource (qmc->dev, res); -if (IS_ERR (qmc->scc_pram)) -return PTR_ERR (qmc->scc_pram); - - qmc->dpram =devm_platform_ioremap_resource_byname (pdev,"dpram" ); -if (IS_ERR (qmc->dpram)) -return PTR_ERR (qmc->dpram); + ret =qmc_init_resources (qmc, pdev); +if (ret) +return ret;/* Parse channels informationss */ ret =qmc_of_parse_chans (qmc, np);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 78/356 soc: fsl: cpm1: qmc: Introduce qmc_{init,exit}_xcc() and their CPM1 version
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herve Codina <[email protected]>
[ Upstream commit de5fdb7d14b34f7fea930f2d72cf0241ec679e72 ]
Current code handles the CPM1 version of QMC and initialize the QMC used SCC. The QUICC Engine (QE) version uses an UCC (Unified Communication Controllers) instead of the SCC (Serial Communication Controllers) used in the CPM1 version. These controllers serve the same purpose and are used in the same way but their inializations are slightly different.
In order to prepare the support for QE version of QMC, introduce qmc_init_xcc() to initialize theses controllers (UCC in QE and SCC in CPM1) and isolate the CPM1 specific SCC initialization in a specific function.
Also introduce qmc_exit_xcc() for consistency to revert operations done in qmc_init_xcc().
Stable-dep-of: cb3daa51db81 ("soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure")
--- drivers/soc/fsl/qe/qmc.c | 66 +++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 21 deletions(-)
drivers/soc/fsl/qe/qmc.c +45 -21
@@ -1293,6 +1293,41 @@ static int qmc_init_resources(struct qmc *qmc, struct platform_device *pdev)return qmc_cpm1_init_resources (qmc, pdev); } +static int qmc_cpm1_init_scc (struct qmc *qmc) +{ +u32 val; +int ret; + +/* Connect the serial (SCC) to TSA */ + ret =tsa_serial_connect (qmc->tsa_serial); +if (ret) +return dev_err_probe (qmc->dev, ret,"Failed to connect TSA serial\n" ); + +/* Init GMSR_H and GMSR_L registers */ + val =SCC_GSMRH_CDS |SCC_GSMRH_CTSS |SCC_GSMRH_CDP |SCC_GSMRH_CTSP ; +qmc_write32 (qmc->scc_regs +SCC_GSMRH , val); + +/* enable QMC mode */ +qmc_write32 (qmc->scc_regs +SCC_GSMRL ,SCC_GSMRL_MODE_QMC ); + +/* Disable and clear interrupts */ +qmc_write16 (qmc->scc_regs +SCC_SCCM ,0x0000 ); +qmc_write16 (qmc->scc_regs +SCC_SCCE ,0x000F ); + +return 0 ; +} + +static int qmc_init_xcc (struct qmc *qmc) +{ +return qmc_cpm1_init_scc (qmc); +} + +static void qmc_exit_xcc (struct qmc *qmc) +{ +/* Disconnect the serial from TSA */ +tsa_serial_disconnect (qmc->tsa_serial); +} +static int qmc_probe (struct platform_device *pdev) {struct device_node *np = pdev->dev.of_node;
@@ -1378,29 +1413,18 @@ static int qmc_probe(struct platform_device *pdev)if (ret)return ret; -/* Connect the serial (SCC) to TSA */ - ret =tsa_serial_connect (qmc->tsa_serial); -if (ret) { -dev_err (qmc->dev,"Failed to connect TSA serial\n" ); +/* Init SCC */ + ret =qmc_init_xcc (qmc); +if (ret)return ret; - } -/* Init GMSR_H and GMSR_L registers */ -qmc_write32 (qmc->scc_regs +SCC_GSMRH , -SCC_GSMRH_CDS |SCC_GSMRH_CTSS |SCC_GSMRH_CDP |SCC_GSMRH_CTSP ); - -/* enable QMC mode */ -qmc_write32 (qmc->scc_regs +SCC_GSMRL ,SCC_GSMRL_MODE_QMC ); - -/* Disable and clear interrupts, set the irq handler */ -qmc_write16 (qmc->scc_regs +SCC_SCCM ,0x0000 ); -qmc_write16 (qmc->scc_regs +SCC_SCCE ,0x000F ); +/* Set the irq handler */ irq =platform_get_irq (pdev,0 );if (irq <0 ) - goto err_tsa_serial_disconnect; + goto err_exit_xcc; ret =devm_request_irq (qmc->dev, irq, qmc_irq_handler,0 ,"qmc" , qmc);if (ret <0 ) - goto err_tsa_serial_disconnect; + goto err_exit_xcc;/* Enable interrupts */ qmc_write16(qmc->scc_regs + SCC_SCCM,
@@ -1420,8 +1444,8 @@ static int qmc_probe(struct platform_device *pdev) err_disable_intr:qmc_write16 (qmc->scc_regs +SCC_SCCM ,0 ); -err_tsa_serial_disconnect: -tsa_serial_disconnect (qmc->tsa_serial); +err_exit_xcc: +qmc_exit_xcc (qmc);return ret; }
@@ -1435,8 +1459,8 @@ static void qmc_remove(struct platform_device *pdev)/* Disable interrupts */ qmc_write16 (qmc->scc_regs +SCC_SCCM ,0 ); -/* Disconnect the serial from TSA */ -tsa_serial_disconnect (qmc->tsa_serial); +/* Exit SCC */ +qmc_exit_xcc (qmc); }static const struct of_device_id qmc_id_table[] = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 79/356 soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herve Codina <[email protected]>
[ Upstream commit cb3daa51db819a172e9524e96e2ed96b4237e51a ]
A kernel test robot detected a missing error code:
qmc.c:1942 qmc_probe() warn: missing error code 'ret'
Indeed, the error returned by platform_get_irq() is checked and the operation is aborted in case of failure but the ret error code is not set in that case.
Set the ret error code.
--- drivers/soc/fsl/qe/qmc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/soc/fsl/qe/qmc.c +3 -1
@@ -1420,8 +1420,10 @@ static int qmc_probe(struct platform_device *pdev)/* Set the irq handler */ irq =platform_get_irq (pdev,0 ); -if (irq <0 ) +if (irq <0 ) { + ret = irq; goto err_exit_xcc; + } ret =devm_request_irq (qmc->dev, irq, qmc_irq_handler,0 ,"qmc" , qmc);if (ret <0 ) goto err_exit_xcc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 80/356 usb: dwc3: gadget: Rewrite endpoint allocation flow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
[ Upstream commit b311048c174da893f47fc09439bc1f6fa2a29589 ]
The driver dwc3 deviates from the programming guide in regard to endpoint configuration. It does this command sequence:
DEPSTARTCFG -> DEPXFERCFG -> DEPCFG
Instead of the suggested flow:
DEPSTARTCFG -> DEPCFG -> DEPXFERCFG
The reasons for this deviation were as follow, quoted:
1) The databook says to do %DWC3_DEPCMD_DEPSTARTCFG for every %USB_REQ_SET_CONFIGURATION and %USB_REQ_SET_INTERFACE (8.1.5). This is incorrect in the scenario of multiple interfaces.
2) The databook does not mention doing more %DWC3_DEPCMD_DEPXFERCFG for new endpoint on alt setting (8.1.6).
Regarding 1), DEPSTARTCFG resets the endpoints' resource and can be a problem if used with SET_INTERFACE request of a multiple interface configuration. But we can still satisfy the programming guide requirement by assigning the endpoint resource as part of usb_ep_enable(). We will only reset endpoint resources on controller initialization and SET_CONFIGURATION request.
Regarding 2), the later versions of the programming guide were updated to clarify this flow (see "Alternate Initialization on SetInterface Request" of the programming guide). As long as the platform has enough physical endpoints, we can assign resource to a new endpoint.
The order of the command sequence will not be a problem to most platforms for the current implementation of the dwc3 driver. However, this order is required in different scenarios (such as initialization during controller's hibernation restore). Let's keep the flow consistent and follow the programming guide.
Stable-dep-of: 5d2fb074dea2 ("usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED")
--- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/ep0.c | 1 + drivers/usb/dwc3/gadget.c | 89 +++++++++++++++++---------------------- drivers/usb/dwc3/gadget.h | 1 + 4 files changed, 41 insertions(+), 51 deletions(-)
drivers/usb/dwc3/core.h +1 -0
@@ -751,6 +751,7 @@ struct dwc3_ep {#define DWC3_EP_PENDING_CLEAR_STALL BIT(11)#define DWC3_EP_TXFIFO_RESIZED BIT(12)#define DWC3_EP_DELAY_STOP BIT(13) +#define DWC3_EP_RESOURCE_ALLOCATED BIT(14)/* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN BIT(31)
drivers/usb/dwc3/ep0.c +1 -0
@@ -646,6 +646,7 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)return -EINVAL ;case USB_STATE_ADDRESS : +dwc3_gadget_start_config (dwc,2 );dwc3_gadget_clear_tx_fifos (dwc); ret =dwc3_ep0_delegate_req (dwc, ctrl);
drivers/usb/dwc3/gadget.c +38 -51
144 lines not on this page · raw message
drivers/usb/dwc3/gadget.h +1 -0
@@ -119,6 +119,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,int __dwc3_gadget_ep_set_halt (struct dwc3_ep *dep,int value,int protocol);void dwc3_ep0_send_delayed_status (struct dwc3 *dwc);void dwc3_stop_active_transfer (struct dwc3_ep *dep,bool force,bool interrupt); +int dwc3_gadget_start_config (struct dwc3 *dwc,unsigned int resource_index);/** * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 81/356 usb: dwc3: ep0: Dont reset resource alloc flag (including ep0)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <[email protected]>
[ Upstream commit 72fca8371f205d654f95b09cd023a71fd5307041 ]
The DWC3_EP_RESOURCE_ALLOCATED flag ensures that the resource of an endpoint is only assigned once. Unless the endpoint is reset, don't clear this flag. Otherwise we may set endpoint resource again, which prevents the driver from initiate transfer after handling a STALL or endpoint halt to the control endpoint.
Commit f2e0eee47038 ("usb: dwc3: ep0: Don't reset resource alloc flag") was fixing the initial issue, but did this only for physical ep1. Since the function dwc3_ep0_stall_and_restart is resetting the flags for both physical endpoints, this also has to be done for ep0.
Stable-dep-of: 5d2fb074dea2 ("usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED")
--- drivers/usb/dwc3/ep0.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/dwc3/ep0.c +2 -1
@@ -231,7 +231,8 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)/* stall is always issued on EP0 */ dep = dwc->eps[0 ];__dwc3_gadget_ep_set_halt (dep,1 , false); - dep->flags =DWC3_EP_ENABLED ; + dep->flags &=DWC3_EP_RESOURCE_ALLOCATED ; + dep->flags |=DWC3_EP_ENABLED ; dwc->delayed_status = false;if (!list_empty (&dep->pending_list)) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 82/356 usb: dwc3: ep0: Dont clear ep0 DWC3_EP_TRANSFER_STARTED
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thinh Nguyen <[email protected]>
[ Upstream commit 5d2fb074dea289c41f5aaf2c3f68286bee370634 ]
The driver cannot issue the End Transfer command to the SETUP transfer. Don't clear DWC3_EP_TRANSFER_STARTED flag to make sure that the driver won't send Start Transfer command again, which can cause no-resource error. For example this can occur if the host issues a reset to the device.
--- drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/dwc3/ep0.c +1 -1
@@ -231,7 +231,7 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)/* stall is always issued on EP0 */ dep = dwc->eps[0 ];__dwc3_gadget_ep_set_halt (dep,1 , false); - dep->flags &=DWC3_EP_RESOURCE_ALLOCATED ; + dep->flags &=DWC3_EP_RESOURCE_ALLOCATED |DWC3_EP_TRANSFER_STARTED ; dep->flags |=DWC3_EP_ENABLED ; dwc->delayed_status = false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 83/356 mmc: mtk-sd: use devm_mmc_alloc_host
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit 7a2fa8eed936b33b22e49b1d2349cd7d02f22710 ]
Allows removing several gotos.
Also fixed some wrong ones.
Added dev_err_probe where EPROBE_DEFER is possible.
Stable-dep-of: 291220451c77 ("mmc: mtk-sd: Fix error handle of probe function")
--- drivers/mmc/host/mtk-sd.c | 55 ++++++++++++++------------------------- 1 file changed, 20 insertions(+), 35 deletions(-)
drivers/mmc/host/mtk-sd.c +20 -35
@@ -2674,20 +2674,18 @@ static int msdc_drv_probe(struct platform_device *pdev) }/* Allocate MMC host for this device */ - mmc =mmc_alloc_host (sizeof (struct msdc_host ), &pdev->dev); + mmc =devm_mmc_alloc_host (&pdev->dev,sizeof (struct msdc_host ));if (!mmc)return -ENOMEM ; host =mmc_priv (mmc); ret =mmc_of_parse (mmc);if (ret) - goto host_free; +return ret; host->base =devm_platform_ioremap_resource (pdev,0 ); -if (IS_ERR (host->base)) { - ret =PTR_ERR (host->base); - goto host_free; - } +if (IS_ERR (host->base)) +return PTR_ERR (host->base); res =platform_get_resource (pdev,IORESOURCE_MEM ,1 );if (res) {
@@ -2698,18 +2696,16 @@ static int msdc_drv_probe(struct platform_device *pdev) ret =mmc_regulator_get_supply (mmc);if (ret) - goto host_free; +return ret; ret =msdc_of_clock_parse (pdev, host);if (ret) - goto host_free; +return ret; host->reset =devm_reset_control_get_optional_exclusive (&pdev->dev,"hrst" ); -if (IS_ERR (host->reset)) { - ret =PTR_ERR (host->reset); - goto host_free; - } +if (IS_ERR (host->reset)) +return PTR_ERR (host->reset);/* only eMMC has crypto property */ if (!(mmc->caps2 &MMC_CAP2_NO_MMC )) {
@@ -2721,30 +2717,24 @@ static int msdc_drv_probe(struct platform_device *pdev) } host->irq =platform_get_irq (pdev,0 ); -if (host->irq <0 ) { - ret = host->irq; - goto host_free; - } +if (host->irq <0 ) +return host->irq; host->pinctrl =devm_pinctrl_get (&pdev->dev); -if (IS_ERR (host->pinctrl)) { - ret =PTR_ERR (host->pinctrl); -dev_err (&pdev->dev,"Cannot find pinctrl!\n" ); - goto host_free; - } +if (IS_ERR (host->pinctrl)) +return dev_err_probe (&pdev->dev,PTR_ERR (host->pinctrl), +"Cannot find pinctrl" ); host->pins_default =pinctrl_lookup_state (host->pinctrl,"default" );if (IS_ERR (host->pins_default)) { - ret =PTR_ERR (host->pins_default);dev_err (&pdev->dev,"Cannot find pinctrl default!\n" ); - goto host_free; +return PTR_ERR (host->pins_default); } host->pins_uhs =pinctrl_lookup_state (host->pinctrl,"state_uhs" );if (IS_ERR (host->pins_uhs)) { - ret =PTR_ERR (host->pins_uhs);dev_err (&pdev->dev,"Cannot find pinctrl uhs!\n" ); - goto host_free; +return PTR_ERR (host->pins_uhs); }/* Support for SDIO eint irq ? */
@@ -2833,14 +2823,14 @@ static int msdc_drv_probe(struct platform_device *pdev) GFP_KERNEL);if (!host->cq_host) { ret = -ENOMEM ; - goto host_free; + goto release_mem; } host->cq_host->caps |=CQHCI_TASK_DESC_SZ_128 ; host->cq_host->mmio = host->base +0x800 ; host->cq_host->ops = &msdc_cmdq_ops; ret =cqhci_init (host->cq_host, mmc, true);if (ret) - goto host_free; + goto release_mem; mmc->max_segs =128 ;/* cqhci 16bit length */ /* 0 size, means 65536 so we don't have to -1 here */
@@ -2877,11 +2867,8 @@ static int msdc_drv_probe(struct platform_device *pdev) host->dma.gpd, host->dma.gpd_addr);if (host->dma.bd)dma_free_coherent (&pdev->dev, -MAX_BD_NUM *sizeof (struct mt_bdma_desc ), - host->dma.bd, host->dma.bd_addr); -host_free: -mmc_free_host (mmc); - +MAX_BD_NUM *sizeof (struct mt_bdma_desc ), + host->dma.bd, host->dma.bd_addr);return ret; }
@@ -2906,9 +2893,7 @@ static void msdc_drv_remove(struct platform_device *pdev)2 *sizeof (struct mt_gpdma_desc ), host->dma.gpd, host->dma.gpd_addr);dma_free_coherent (&pdev->dev,MAX_BD_NUM *sizeof (struct mt_bdma_desc ), - host->dma.bd, host->dma.bd_addr); - -mmc_free_host (mmc); + host->dma.bd, host->dma.bd_addr); }static void msdc_save_reg (struct msdc_host *host)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 84/356 mmc: mtk-sd: Fix error handle of probe function
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy-ld Lu <[email protected]>
[ Upstream commit 291220451c775a054cedc4fab4578a1419eb6256 ]
In the probe function, it goes to 'release_mem' label and returns after some procedure failure. But if the clocks (partial or all) have been enabled previously, they would not be disabled in msdc_runtime_suspend, since runtime PM is not yet enabled for this case.
That cause mmc related clocks always on during system suspend and block suspend flow. Below log is from a SDCard issue of MT8196 chromebook, it returns -ETIMEOUT while polling clock stable in the msdc_ungate_clock() and probe failed, but the enabled clocks could not be disabled anyway.
[ 129.059253] clk_chk_dev_pm_suspend() [ 129.350119] suspend warning: msdcpll is on [ 129.354494] [ck_msdc30_1_sel : enabled, 1, 1, 191999939, ck_msdcpll_d2] [ 129.362787] [ck_msdcpll_d2 : enabled, 1, 1, 191999939, msdcpll] [ 129.371041] [ck_msdc30_1_ck : enabled, 1, 1, 191999939, ck_msdc30_1_sel] [ 129.379295] [msdcpll : enabled, 1, 1, 383999878, clk26m]
Add a new 'release_clk' label and reorder the error handle functions to make sure the clocks be disabled after probe failure.
Message-ID: <[email protected]>
--- drivers/mmc/host/mtk-sd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/mmc/host/mtk-sd.c +5 -4
@@ -2813,7 +2813,7 @@ static int msdc_drv_probe(struct platform_device *pdev) ret =msdc_ungate_clock (host);if (ret) {dev_err (&pdev->dev,"Cannot ungate clocks!\n" ); - goto release_mem; + goto release_clk; }msdc_init_hw (host);
@@ -2823,14 +2823,14 @@ static int msdc_drv_probe(struct platform_device *pdev) GFP_KERNEL);if (!host->cq_host) { ret = -ENOMEM ; - goto release_mem; + goto release; } host->cq_host->caps |=CQHCI_TASK_DESC_SZ_128 ; host->cq_host->mmio = host->base +0x800 ; host->cq_host->ops = &msdc_cmdq_ops; ret =cqhci_init (host->cq_host, mmc, true);if (ret) - goto release_mem; + goto release; mmc->max_segs =128 ;/* cqhci 16bit length */ /* 0 size, means 65536 so we don't have to -1 here */
@@ -2857,9 +2857,10 @@ static int msdc_drv_probe(struct platform_device *pdev) end:pm_runtime_disable (host->dev); release: -platform_set_drvdata (pdev,NULL );msdc_deinit_hw (host); +release_clk:msdc_gate_clock (host); +platform_set_drvdata (pdev,NULL ); release_mem:if (host->dma.gpd) dma_free_coherent(&pdev->dev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 85/356 mmc: mtk-sd: fix devm_clk_get_optional usage
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <[email protected]>
[ Upstream commit ed299eda8fbb37cb0e05c7001ab6a6b2627ec087 ]
This already returns NULL when not found. However, it can return EPROBE_DEFER and should thus return here.
Stable-dep-of: 2508925fb346 ("mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting")
--- drivers/mmc/host/mtk-sd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mmc/host/mtk-sd.c +2 -3
@@ -2711,9 +2711,8 @@ static int msdc_drv_probe(struct platform_device *pdev)if (!(mmc->caps2 &MMC_CAP2_NO_MMC )) { host->crypto_clk =devm_clk_get_optional (&pdev->dev,"crypto" );if (IS_ERR (host->crypto_clk)) - host->crypto_clk =NULL ; -else - mmc->caps2 |=MMC_CAP2_CRYPTO ; +return PTR_ERR (host->crypto_clk); + mmc->caps2 |=MMC_CAP2_CRYPTO ; } host->irq =platform_get_irq (pdev,0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 86/356 mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy-ld Lu <[email protected]>
[ Upstream commit 2508925fb346661bad9f50b497d7ac7d0b6085d0 ]
Currently, the MMC_CAP2_CRYPTO flag is set by default for eMMC hosts. However, this flag should not be set for hosts that do not support inline encryption.
The 'crypto' clock, as described in the documentation, is used for data encryption and decryption. Therefore, only hosts that are configured with this 'crypto' clock should have the MMC_CAP2_CRYPTO flag set.
Message-ID: <[email protected]>
--- drivers/mmc/host/mtk-sd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/host/mtk-sd.c +2 -1
@@ -2712,7 +2712,8 @@ static int msdc_drv_probe(struct platform_device *pdev) host->crypto_clk =devm_clk_get_optional (&pdev->dev,"crypto" );if (IS_ERR (host->crypto_clk))return PTR_ERR (host->crypto_clk); - mmc->caps2 |=MMC_CAP2_CRYPTO ; +else if (host->crypto_clk) + mmc->caps2 |=MMC_CAP2_CRYPTO ; } host->irq =platform_get_irq (pdev,0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 87/356 zram: split memory-tracking and ac-time tracking
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <[email protected]>
[ Upstream commit a7a0350583ba51d8cde6180bb51d704b89a3b29e ]
ZRAM_MEMORY_TRACKING enables two features:
- per-entry ac-time tracking
- debugfs interface
The latter one is the reason why memory-tracking depends on DEBUG_FS, while the former one is used far beyond debugging these days. Namely ac-time is used for fine grained writeback of idle entries (pages).
Move ac-time tracking under its own config option so that it can be enabled (along with writeback) on systems without DEBUG_FS.
Stable-dep-of: d37da422edb0 ("zram: clear IDLE flag in mark_idle()")
--- Documentation/admin-guide/blockdev/zram.rst | 2 +- drivers/block/zram/Kconfig | 11 ++++++++- drivers/block/zram/zram_drv.c | 27 ++++++++++----------- drivers/block/zram/zram_drv.h | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-)
Documentation/admin-guide/blockdev/zram.rst +1 -1
@@ -328,7 +328,7 @@ as idle:: From now on, any pages on zram are idle pages. The idle mark will be removed until someone requests access of the block. IOW, unless there is access request, those pages are still idle pages. -Additionally, when CONFIG_ZRAM_MEMORY_TRACKING is enabled pages can be +Additionally, when CONFIG_ZRAM_TRACK_ENTRY_ACTIME is enabled pages can be marked as idle based on how long (in seconds) it's been since they were last accessed::
drivers/block/zram/Kconfig +10 -1
@@ -69,9 +69,18 @@ config ZRAM_WRITEBACK See Documentation/admin-guide/blockdev/zram.rst for more information. +config ZRAM_TRACK_ENTRY_ACTIME + bool "Track access time of zram entries" + depends on ZRAM + help + With this feature zram tracks access time of every stored + entry (page), which can be used for a more fine grained IDLE + pages writeback. + config ZRAM_MEMORY_TRACKING bool "Track zRam block status" depends on ZRAM && DEBUG_FS + select ZRAM_TRACK_ENTRY_ACTIME help With this feature, admin can track the state of allocated blocks of zRAM. Admin could see the information via
@@ -86,4 +95,4 @@ config ZRAM_MULTI_COMP This will enable multi-compression streams, so that ZRAM can re-compress pages using a potentially slower but more effective compression algorithm. Note, that IDLE page recompression - requires ZRAM_MEMORY_TRACKING. + requires ZRAM_TRACK_ENTRY_ACTIME.
drivers/block/zram/zram_drv.c +13 -14
@@ -174,6 +174,14 @@ static inline u32 zram_get_priority(struct zram *zram, u32 index)return prio &ZRAM_COMP_PRIORITY_MASK ; } +static void zram_accessed (struct zram *zram,u32 index) +{ +zram_clear_flag (zram, index,ZRAM_IDLE ); +#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME + zram->table[index].ac_time =ktime_get_boottime (); +#endif +} +static inline void update_used_max (struct zram *zram,const unsigned long pages) {
@@ -293,8 +301,9 @@ static void mark_idle(struct zram *zram, ktime_t cutoff)zram_slot_lock (zram, index);if (zram_allocated (zram, index) && !zram_test_flag (zram, index,ZRAM_UNDER_WB )) { -#ifdef CONFIG_ZRAM_MEMORY_TRACKING - is_idle = !cutoff ||ktime_after (cutoff, zram->table[index].ac_time); +#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME + is_idle = !cutoff ||ktime_after (cutoff, + zram->table[index].ac_time);#endif if (is_idle)zram_set_flag (zram, index,ZRAM_IDLE );
@@ -317,7 +326,7 @@ static ssize_t idle_store(struct device *dev,*/ u64 age_sec; -if (IS_ENABLED (CONFIG_ZRAM_MEMORY_TRACKING ) && !kstrtoull (buf,0 , &age_sec)) +if (IS_ENABLED (CONFIG_ZRAM_TRACK_ENTRY_ACTIME ) && !kstrtoull (buf,0 , &age_sec)) cutoff_time =ktime_sub (ktime_get_boottime (),ns_to_ktime (age_sec *NSEC_PER_SEC ));else
@@ -844,12 +853,6 @@ static void zram_debugfs_destroy(void)debugfs_remove_recursive (zram_debugfs_root); } -static void zram_accessed (struct zram *zram,u32 index) -{ -zram_clear_flag (zram, index,ZRAM_IDLE ); - zram->table[index].ac_time =ktime_get_boottime (); -} -static ssize_t read_block_state (struct file *file,char __user *buf,size_t count,loff_t *ppos) {
@@ -933,10 +936,6 @@ static void zram_debugfs_unregister(struct zram *zram)#else static void zram_debugfs_create (void ) {};static void zram_debugfs_destroy (void ) {}; -static void zram_accessed (struct zram *zram,u32 index) -{ -zram_clear_flag (zram, index,ZRAM_IDLE ); -};static void zram_debugfs_register (struct zram *zram) {};static void zram_debugfs_unregister (struct zram *zram) {};#endif
@@ -1257,7 +1256,7 @@ static void zram_free_page(struct zram *zram, size_t index) {unsigned long handle; -#ifdef CONFIG_ZRAM_MEMORY_TRACKING +#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME zram->table[index].ac_time =0 ;#endif if (zram_test_flag (zram, index,ZRAM_IDLE ))
drivers/block/zram/zram_drv.h +1 -1
@@ -69,7 +69,7 @@ struct zram_table_entry {unsigned long element; };unsigned long flags; -#ifdef CONFIG_ZRAM_MEMORY_TRACKING +#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME ktime_t ac_time;#endif };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 88/356 zram: do not mark idle slots that cannot be idle
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <[email protected]>
[ Upstream commit b967fa1ba72b5da2b6d9bf95f0b13420a59e0701 ]
ZRAM_SAME slots cannot be post-processed (writeback or recompress) so do not mark them ZRAM_IDLE. Same with ZRAM_WB slots, they cannot be ZRAM_IDLE because they are not in zsmalloc pool anymore.
Stable-dep-of: d37da422edb0 ("zram: clear IDLE flag in mark_idle()")
--- drivers/block/zram/zram_drv.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
drivers/block/zram/zram_drv.c +18 -7
@@ -297,17 +297,28 @@ static void mark_idle(struct zram *zram, ktime_t cutoff)/* * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race. * See the comment in writeback_store. +* +* Also do not mark ZRAM_SAME slots as ZRAM_IDLE, because no +* post-processing (recompress, writeback) happens to the +* ZRAM_SAME slot. +* +* And ZRAM_WB slots simply cannot be ZRAM_IDLE. */ zram_slot_lock (zram, index); -if (zram_allocated (zram, index) && - !zram_test_flag (zram, index,ZRAM_UNDER_WB )) { +if (!zram_allocated (zram, index) || +zram_test_flag (zram, index,ZRAM_WB ) || +zram_test_flag (zram, index,ZRAM_UNDER_WB ) || +zram_test_flag (zram, index,ZRAM_SAME )) { +zram_slot_unlock (zram, index); +continue ; + } +#ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME - is_idle = !cutoff ||ktime_after (cutoff, - zram->table[index].ac_time); + is_idle = !cutoff || +ktime_after (cutoff, zram->table[index].ac_time);#endif -if (is_idle) -zram_set_flag (zram, index,ZRAM_IDLE ); - } +if (is_idle) +zram_set_flag (zram, index,ZRAM_IDLE );zram_slot_unlock (zram, index); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 89/356 zram: clear IDLE flag in mark_idle()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <[email protected]>
[ Upstream commit d37da422edb0664a2037e6d7d42fe6d339aae78a ]
If entry does not fulfill current mark_idle() parameters, e.g. cutoff time, then we should clear its ZRAM_IDLE from previous mark_idle() invocations.
Consider the following case:
- mark_idle() cutoff time 8h
- mark_idle() cutoff time 4h
- writeback() idle - will writeback entries with cutoff time 8h, while it should only pick entries with cutoff time 4h
The bug was reported by Shin Kawamura.
--- drivers/block/zram/zram_drv.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/block/zram/zram_drv.c +2 -0
@@ -319,6 +319,8 @@ static void mark_idle(struct zram *zram, ktime_t cutoff)#endif if (is_idle)zram_set_flag (zram, index,ZRAM_IDLE ); +else +zram_clear_flag (zram, index,ZRAM_IDLE );zram_slot_unlock (zram, index); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 90/356 iommu/arm-smmu: Defer probe of clients after smmu device bound
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pratyush Brahma <[email protected]>
commit 229e6ee43d2a160a1592b83aad620d6027084aad upstream.
Null pointer dereference occurs due to a race between smmu driver probe and client driver probe, when of_dma_configure() for client is called after the iommu_device_register() for smmu driver probe has executed but before the driver_bound() for smmu driver has been called.
Following is how the race occurs:
T1:Smmu device probe T2: Client device probe
really_probe()arm_smmu_device_probe()iommu_device_register()
really_probe() platform_dma_configure() of_dma_configure() of_dma_configure_id() of_iommu_configure() iommu_probe_device() iommu_init_device() arm_smmu_probe_device() arm_smmu_get_by_fwnode() driver_find_device_by_fwnode() driver_find_device() next_device() klist_next() /* null ptr assigned to smmu */ /* null ptr dereference while smmu->streamid_mask */
driver_bound()
klist_add_tail()
When this null smmu pointer is dereferenced later in arm_smmu_probe_device, the device crashes.
Fix this by deferring the probe of the client device until the smmu device has bound to the arm smmu driver.
--- drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/iommu/arm/arm-smmu/arm-smmu.c +11 -0
@@ -1359,6 +1359,17 @@ static struct iommu_device *arm_smmu_pro goto out_free; }else if (fwspec && fwspec->ops == &arm_smmu_ops) { smmu =arm_smmu_get_by_fwnode (fwspec->iommu_fwnode); + +/* +* Defer probe if the relevant SMMU instance hasn't finished +* probing yet. This is a fragile hack and we'd ideally +* avoid this race in the core code. Until that's ironed +* out, however, this is the most pragmatic option on the +* table. +*/ +if (!smmu) +return ERR_PTR (dev_err_probe (dev, -EPROBE_DEFER , +"smmu dev has not bound yet\n" )); }else {return ERR_PTR (-ENODEV ); }
Greg Kroah-Hartman
maintainerPATCH 91/356 powerpc/vdso: Refactor CFLAGS for CVDSO build
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe Leroy <[email protected]>
[ Upstream commit a6b67eb09963af29991625862cbb4f56b85954ed ]
In order to avoid two much duplication when we add new VDSO functionnalities in C like getrandom, refactor common CFLAGS.
Stable-dep-of: d677ce521334 ("powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang")
--- arch/powerpc/kernel/vdso/Makefile | 32 +++++++++++++------------------ 1 file changed, 13 insertions(+), 19 deletions(-)
arch/powerpc/kernel/vdso/Makefile +13 -19
@@ -10,28 +10,11 @@ obj-vdso64 = sigtramp64-64.o gettimeofday-64.o datapage-64.o cacheflush-64.o not ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday-32.o += -include $(c-gettimeofday-y) - CFLAGS_vgettimeofday-32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) - CFLAGS_vgettimeofday-32.o += $(call cc-option, -fno-stack-protector) - CFLAGS_vgettimeofday-32.o += -DDISABLE_BRANCH_PROFILING - CFLAGS_vgettimeofday-32.o += -ffreestanding -fasynchronous-unwind-tables - CFLAGS_REMOVE_vgettimeofday-32.o = $(CC_FLAGS_FTRACE) - CFLAGS_REMOVE_vgettimeofday-32.o += -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc - # This flag is supported by clang for 64-bit but not 32-bit so it will cause - # an unused command line flag warning for this file. - ifdef CONFIG_CC_IS_CLANG - CFLAGS_REMOVE_vgettimeofday-32.o += -fno-stack-clash-protection - endif - CFLAGS_vgettimeofday-64.o += -include $(c-gettimeofday-y) - CFLAGS_vgettimeofday-64.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) - CFLAGS_vgettimeofday-64.o += $(call cc-option, -fno-stack-protector) - CFLAGS_vgettimeofday-64.o += -DDISABLE_BRANCH_PROFILING - CFLAGS_vgettimeofday-64.o += -ffreestanding -fasynchronous-unwind-tables - CFLAGS_REMOVE_vgettimeofday-64.o = $(CC_FLAGS_FTRACE) # Go prior to 1.16.x assumes r30 is not clobbered by any VDSO code. That used to be true # by accident when the VDSO was hand-written asm code, but may not be now that the VDSO is # compiler generated. To avoid breaking Go tell GCC not to use r30. Impact on code # generation is minimal, it will just use r29 instead. - CFLAGS_vgettimeofday-64.o += $(call cc-option, -ffixed-r30) + CFLAGS_vgettimeofday-64.o += -include $(c-gettimeofday-y) $(call cc-option, -ffixed-r30) endif # Build rules
@@ -54,6 +37,11 @@ KASAN_SANITIZE := n KCSAN_SANITIZE := n ccflags-y := -fno-common -fno-builtin +ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN) +ccflags-y += $(call cc-option, -fno-stack-protector) +ccflags-y += -DDISABLE_BRANCH_PROFILING +ccflags-y += -ffreestanding -fasynchronous-unwind-tables +ccflags-remove-y := $(CC_FLAGS_FTRACE) ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS) ldflags-$(CONFIG_LD_IS_LLD) += $(call cc-option,--ld-path=$(LD),-fuse-ld=lld) ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
@@ -62,6 +50,12 @@ ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WAR ldflags-y += $(filter-out $(CC_AUTO_VAR_INIT_ZERO_ENABLER) $(CC_FLAGS_FTRACE) -Wa$(comma)%, $(KBUILD_CFLAGS)) CC32FLAGS := -m32 +CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc + # This flag is supported by clang for 64-bit but not 32-bit so it will cause + # an unused command line flag warning for this file. +ifdef CONFIG_CC_IS_CLANG +CC32FLAGSREMOVE += -fno-stack-clash-protection +endif LD32FLAGS := -Wl,-soname=linux-vdso32.so.1 AS32FLAGS := -D__VDSO32__
@@ -108,7 +102,7 @@ quiet_cmd_vdso32ld_and_check = VDSO32L $@ quiet_cmd_vdso32as = VDSO32A $@ cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) $(AS32FLAGS) -c -o $@ $< quiet_cmd_vdso32cc = VDSO32C $@ - cmd_vdso32cc = $(VDSOCC) $(c_flags) $(CC32FLAGS) -c -o $@ $< + cmd_vdso32cc = $(VDSOCC) $(filter-out $(CC32FLAGSREMOVE), $(c_flags)) $(CC32FLAGS) -c -o $@ $< quiet_cmd_vdso64ld_and_check = VDSO64L $@ cmd_vdso64ld_and_check = $(VDSOCC) $(ldflags-y) $(LD64FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 92/356 powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
[ Upstream commit d677ce521334d8f1f327cafc8b1b7854b0833158 ]
Under certain conditions, the 64-bit '-mstack-protector-guard' flags may end up in the 32-bit vDSO flags, resulting in build failures due to the structure of clang's argument parsing of the stack protector options, which validates the arguments of the stack protector guard flags unconditionally in the frontend, choking on the 64-bit values when targeting 32-bit:
clang: error: invalid value 'r13' in 'mstack-protector-guard-reg=', expected one of: r2
clang: error: invalid value 'r13' in 'mstack-protector-guard-reg=', expected one of: r2 make[3]: *** [arch/powerpc/kernel/vdso/Makefile:85: arch/powerpc/kernel/vdso/vgettimeofday-32.o] Error 1 make[3]: *** [arch/powerpc/kernel/vdso/Makefile:87: arch/powerpc/kernel/vdso/vgetrandom-32.o] Error 1
Remove these flags by adding them to the CC32FLAGSREMOVE variable, which already handles situations similar to this. Additionally, reformat and align a comment better for the expanding CONFIG_CC_IS_CLANG block.
--- arch/powerpc/kernel/vdso/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/powerpc/kernel/vdso/Makefile +6 -2
@@ -51,10 +51,14 @@ ldflags-y += $(filter-out $(CC_AUTO_VAR_INIT_ZERO_ENABLER) $(CC_FLAGS_FTRACE) -W CC32FLAGS := -m32 CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc - # This flag is supported by clang for 64-bit but not 32-bit so it will cause - # an unused command line flag warning for this file. ifdef CONFIG_CC_IS_CLANG +# This flag is supported by clang for 64-bit but not 32-bit so it will cause +# an unused command line flag warning for this file. CC32FLAGSREMOVE += -fno-stack-clash-protection +# -mstack-protector-guard values from the 64-bit build are not valid for the +# 32-bit one. clang validates the values passed to these arguments during +# parsing, even when -fno-stack-protector is passed afterwards. +CC32FLAGSREMOVE += -mstack-protector-guard% endif LD32FLAGS := -Wl,-soname=linux-vdso32.so.1 AS32FLAGS := -D__VDSO32__
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 93/356 ntp: Remove invalid cast in time offset math
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Dalmas <[email protected]>
commit f5807b0606da7ac7c1b74a386b22134ec7702d05 upstream.
Due to an unsigned cast, adjtimex() returns the wrong offest when using ADJ_MICRO and the offset is negative. In this case a small negative offset returns approximately 4.29 seconds (~ 2^32/1000 milliseconds) due to the unsigned cast of the negative offset.
This cast was added when the kernel internal struct timex was changed to use type long long for the time offset value to address the problem of a 64bit/32bit division on 32bit systems.
The correct cast would have been (s32), which is correct as time_offset can only be in the range of [INT_MIN..INT_MAX] because the shift constant used for calculating it is 32. But that's non-obvious.
Remove the cast and use div_s64() to cure the issue.
[ tglx: Fix white space damage, use div_s64() and amend the change log ]
--- kernel/time/ntp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/ntp.c +1 -1
@@ -796,7 +796,7 @@ int __do_adjtimex(struct __kernel_timex txc->offset =shift_right (time_offset *NTP_INTERVAL_FREQ ,NTP_SCALE_SHIFT );if (!(time_status &STA_NANO )) - txc->offset = (u32 )txc->offset /NSEC_PER_USEC ; + txc->offset =div_s64 (txc->offset,NSEC_PER_USEC ); } result = time_state;/* mostly `TIME_OK' */
Greg Kroah-Hartman
maintainerPATCH 94/356 driver core: fw_devlink: Improve logs for cycle detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravana Kannan <[email protected]>
[ Upstream commit 6e7ad1aebb4fc9fed0217dd50ef6e58a53f17d81 ]
The links in a cycle are not all logged in a consistent manner or not logged at all. Make them consistent by adding a "cycle:" string and log all the link in the cycles (even the child ==> parent dependency) so that it's easier to debug cycle detection code. Also, mark the start and end of a cycle so it's easy to tell when multiple cycles are logged back to back.
Stable-dep-of: bac3b10b78e5 ("driver core: fw_devlink: Stop trying to optimize cycle detection logic")
--- drivers/base/core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/base/core.c +9 -2
@@ -125,7 +125,7 @@ static void __fwnode_link_del(struct fwnode_link *link)*/ static void __fwnode_link_cycle (struct fwnode_link *link) { -pr_debug ("%pfwf: Relaxing link with %pfwf\n" , +pr_debug ("%pfwf: cycle: depends on %pfwf\n" , link->consumer, link->supplier); link->flags |=FWLINK_FLAG_CYCLE ; }
@@ -1959,6 +1959,7 @@ static bool __fw_devlink_relax_cycles(struct device *con,/* Termination condition. */ if (sup_dev == con) { +pr_debug ("----- cycle: start -----\n" ); ret = true; goto out; }
@@ -1990,8 +1991,11 @@ static bool __fw_devlink_relax_cycles(struct device *con,else par_dev =fwnode_get_next_parent_dev (sup_handle); -if (par_dev &&__fw_devlink_relax_cycles (con, par_dev->fwnode)) +if (par_dev &&__fw_devlink_relax_cycles (con, par_dev->fwnode)) { +pr_debug ("%pfwf: cycle: child of %pfwf\n" , sup_handle, + par_dev->fwnode); ret = true; + }if (!sup_dev) goto out;
@@ -2007,6 +2011,8 @@ static bool __fw_devlink_relax_cycles(struct device *con,if (__fw_devlink_relax_cycles (con, dev_link->supplier->fwnode)) { +pr_debug ("%pfwf: cycle: depends on %pfwf\n" , sup_handle, + dev_link->supplier->fwnode);fw_devlink_relax_link (dev_link); dev_link->flags |=DL_FLAG_CYCLE ; ret = true;
@@ -2086,6 +2092,7 @@ static int fw_devlink_create_devlink(struct device *con,if (__fw_devlink_relax_cycles (con, sup_handle)) {__fwnode_link_cycle (link); flags =fw_devlink_get_flags (link->flags); +pr_debug ("----- cycle: end -----\n" );dev_info (con,"Fixed dependency cycle(s) with %pfwf\n" , sup_handle); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 95/356 driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravana Kannan <[email protected]>
[ Upstream commit b7e1241d8f77ed64404a5e4450f43a319310fc91 ]
A fwnode link between specific supplier-consumer fwnodes can be added multiple times for multiple reasons. If that dependency doesn't exist, deleting the fwnode link once doesn't guarantee that it won't get created again.
So, add FWLINK_FLAG_IGNORE flag to mark a fwnode link as one that needs to be completely ignored. Since a fwnode link's flags is an OR of all the flags passed to all the fwnode_link_add() calls to create that specific fwnode link, the FWLINK_FLAG_IGNORE flag is preserved and can be used to mark a fwnode link as on that need to be completely ignored until it is deleted.
Stable-dep-of: bac3b10b78e5 ("driver core: fw_devlink: Stop trying to optimize cycle detection logic")
--- drivers/base/core.c | 9 ++++++++- include/linux/fwnode.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-)
drivers/base/core.c +8 -1
@@ -1025,7 +1025,8 @@ static struct fwnode_handle *fwnode_links_check_suppliers(return NULL ;list_for_each_entry (link, &fwnode->suppliers, c_hook) -if (!(link->flags &FWLINK_FLAG_CYCLE )) +if (!(link->flags & + (FWLINK_FLAG_CYCLE |FWLINK_FLAG_IGNORE )))return link->supplier;return NULL ;
@@ -1976,6 +1977,9 @@ static bool __fw_devlink_relax_cycles(struct device *con, }list_for_each_entry (link, &sup_handle->suppliers, c_hook) { +if (link->flags &FWLINK_FLAG_IGNORE ) +continue ; +if (__fw_devlink_relax_cycles (con, link->supplier)) {__fwnode_link_cycle (link); ret = true;
@@ -2054,6 +2058,9 @@ static int fw_devlink_create_devlink(struct device *con,int ret =0 ;u32 flags; +if (link->flags &FWLINK_FLAG_IGNORE ) +return 0 ; +if (con->fwnode == link->consumer) flags =fw_devlink_get_flags (link->flags);else
include/linux/fwnode.h +2 -0
@@ -51,8 +51,10 @@ struct fwnode_handle {* fwnode link flags * * CYCLE: The fwnode link is part of a cycle. Don't defer probe. +* IGNORE: Completely ignore this link, even during cycle detection. */ #define FWLINK_FLAG_CYCLE BIT(0) +#define FWLINK_FLAG_IGNORE BIT(1)struct fwnode_link {struct fwnode_handle *supplier;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 96/356 driver core: fw_devlink: Stop trying to optimize cycle detection logic
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saravana Kannan <[email protected]>
[ Upstream commit bac3b10b78e54b7da3cede397258f75a2180609b ]
In attempting to optimize fw_devlink runtime, I introduced numerous cycle detection bugs by foregoing cycle detection logic under specific conditions. Each fix has further narrowed the conditions for optimization.
It's time to give up on these optimization attempts and just run the cycle detection logic every time fw_devlink tries to create a device link.
The specific bug report that triggered this fix involved a supplier fwnode that never gets a device created for it. Instead, the supplier fwnode is represented by the device that corresponds to an ancestor fwnode.
In this case, fw_devlink didn't do any cycle detection because the cycle detection logic is only run when a device link is created between the devices that correspond to the actual consumer and supplier fwnodes.
With this change, fw_devlink will run cycle detection logic even when creating SYNC_STATE_ONLY proxy device links from a device that is an ancestor of a consumer fwnode.
--- drivers/base/core.c | 55 ++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 31 deletions(-)
drivers/base/core.c +24 -31
@@ -1936,10 +1936,10 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode)* * Return true if one or more cycles were found. Otherwise, return false. */ -static bool __fw_devlink_relax_cycles (struct device *con, +static bool __fw_devlink_relax_cycles (struct fwnode_handle *con_handle,struct fwnode_handle *sup_handle) { -struct device *sup_dev =NULL , *par_dev =NULL ; +struct device *sup_dev =NULL , *par_dev =NULL , *con_dev =NULL ;struct fwnode_link *link;struct device_link *dev_link;bool ret = false;
@@ -1956,22 +1956,22 @@ static bool __fw_devlink_relax_cycles(struct device *con, sup_handle->flags |=FWNODE_FLAG_VISITED ; - sup_dev =get_dev_from_fwnode (sup_handle); -/* Termination condition. */ -if (sup_dev == con) { +if (sup_handle == con_handle) {pr_debug ("----- cycle: start -----\n" ); ret = true; goto out; } + sup_dev =get_dev_from_fwnode (sup_handle); + con_dev =get_dev_from_fwnode (con_handle);/* * If sup_dev is bound to a driver and @con hasn't started binding to a * driver, sup_dev can't be a consumer of @con. So, no need to check * further. */ if (sup_dev && sup_dev->links.status ==DL_DEV_DRIVER_BOUND && - con->links.status ==DL_DEV_NO_DRIVER ) { + con_dev && con_dev->links.status ==DL_DEV_NO_DRIVER ) { ret = false; goto out; }
@@ -1980,7 +1980,7 @@ static bool __fw_devlink_relax_cycles(struct device *con,if (link->flags &FWLINK_FLAG_IGNORE )continue ; -if (__fw_devlink_relax_cycles (con, link->supplier)) { +if (__fw_devlink_relax_cycles (con_handle, link->supplier)) {__fwnode_link_cycle (link); ret = true; }
@@ -1995,7 +1995,7 @@ static bool __fw_devlink_relax_cycles(struct device *con,else par_dev =fwnode_get_next_parent_dev (sup_handle); -if (par_dev &&__fw_devlink_relax_cycles (con, par_dev->fwnode)) { +if (par_dev &&__fw_devlink_relax_cycles (con_handle, par_dev->fwnode)) {pr_debug ("%pfwf: cycle: child of %pfwf\n" , sup_handle, par_dev->fwnode); ret = true;
@@ -2013,7 +2013,7 @@ static bool __fw_devlink_relax_cycles(struct device *con, !(dev_link->flags & DL_FLAG_CYCLE))continue ; -if (__fw_devlink_relax_cycles (con, +if (__fw_devlink_relax_cycles (con_handle, dev_link->supplier->fwnode)) {pr_debug ("%pfwf: cycle: depends on %pfwf\n" , sup_handle, dev_link->supplier->fwnode);
@@ -2061,11 +2061,6 @@ static int fw_devlink_create_devlink(struct device *con,if (link->flags &FWLINK_FLAG_IGNORE )return 0 ; -if (con->fwnode == link->consumer) - flags =fw_devlink_get_flags (link->flags); -else - flags =FW_DEVLINK_FLAGS_PERMISSIVE ; -/* * In some cases, a device P might also be a supplier to its child node * C. However, this would defer the probe of C until the probe of P
@@ -2086,25 +2081,23 @@ static int fw_devlink_create_devlink(struct device *con,return -EINVAL ;/* -* SYNC_STATE_ONLY device links don't block probing and supports cycles. -* So, one might expect that cycle detection isn't necessary for them. -* However, if the device link was marked as SYNC_STATE_ONLY because -* it's part of a cycle, then we still need to do cycle detection. This -* is because the consumer and supplier might be part of multiple cycles -* and we need to detect all those cycles. +* Don't try to optimize by not calling the cycle detection logic under +* certain conditions. There's always some corner case that won't get +* detected. */ -if (!device_link_flag_is_sync_state_only (flags) || - flags &DL_FLAG_CYCLE ) { -device_links_write_lock (); -if (__fw_devlink_relax_cycles (con, sup_handle)) { -__fwnode_link_cycle (link); - flags =fw_devlink_get_flags (link->flags); -pr_debug ("----- cycle: end -----\n" ); -dev_info (con,"Fixed dependency cycle(s) with %pfwf\n" , - sup_handle); - } -device_links_write_unlock (); +device_links_write_lock (); +if (__fw_devlink_relax_cycles (link->consumer, sup_handle)) { +__fwnode_link_cycle (link); +pr_debug ("----- cycle: end -----\n" ); +pr_info ("%pfwf: Fixed dependency cycle(s) with %pfwf\n" , + link->consumer, sup_handle); } +device_links_write_unlock (); + +if (con->fwnode == link->consumer) + flags =fw_devlink_get_flags (link->flags); +else + flags =FW_DEVLINK_FLAGS_PERMISSIVE ;if (sup_handle->flags &FWNODE_FLAG_NOT_DEVICE ) sup_dev =fwnode_get_next_parent_dev (sup_handle);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 97/356 f2fs: fix to drop all discards after creating snapshot on lvm device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit bc8aeb04fd80cb8cfae3058445c84410fd0beb5e ]
Piergiorgio reported a bug in bugzilla as below:
------------[ cut here ]------------ WARNING: CPU: 2 PID: 969 at fs/f2fs/segment.c:1330 RIP: 0010:__submit_discard_cmd+0x27d/0x400 [f2fs] Call Trace: __issue_discard_cmd+0x1ca/0x350 [f2fs] issue_discard_thread+0x191/0x480 [f2fs] kthread+0xcf/0x100 ret_from_fork+0x31/0x50 ret_from_fork_asm+0x1a/0x30
w/ below testcase, it can reproduce this bug quickly:
- pvcreate /dev/vdb
- vgcreate myvg1 /dev/vdb
- lvcreate -L 1024m -n mylv1 myvg1
- mount /dev/myvg1/mylv1 /mnt/f2fs
- dd if=/dev/zero of=/mnt/f2fs/file bs=1M count=20
- sync
- rm /mnt/f2fs/file
- sync
- lvcreate -L 1024m -s -n mylv1-snapshot /dev/myvg1/mylv1
- umount /mnt/f2fs
The root cause is: it will update discard_max_bytes of mounted lvm device to zero after creating snapshot on this lvm device, then, __submit_discard_cmd() will pass parameter @nr_sects w/ zero value to __blkdev_issue_discard(), it returns a NULL bio pointer, result in panic.
This patch changes as below for fixing:
1. Let's drop all remained discards in f2fs_unfreeze() if snapshot of lvm device is created.
2. Checking discard_max_bytes before submitting discard during __submit_discard_cmd().
--- fs/f2fs/segment.c | 9 +++++++++ fs/f2fs/super.c | 12 ++++++++++++ 2 files changed, 21 insertions(+)
fs/f2fs/segment.c +9 -0
@@ -1282,6 +1282,15 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, }#endif +/* +* stop issuing discard for any of below cases: +* 1. device is conventional zone, but it doesn't support discard. +* 2. device is regulare device, after snapshot it doesn't support +* discard. +*/ +if (!bdev_max_discard_sectors (bdev)) +return -EOPNOTSUPP ; +trace_f2fs_issue_discard (bdev, dc->di.start, dc->di.len); lstart = dc->di.lstart;
fs/f2fs/super.c +12 -0
@@ -1735,6 +1735,18 @@ static int f2fs_freeze(struct super_block *sb)static int f2fs_unfreeze (struct super_block *sb) { +struct f2fs_sb_info *sbi =F2FS_SB (sb); + +/* +* It will update discard_max_bytes of mounted lvm device to zero +* after creating snapshot on this lvm device, let's drop all +* remained discards. +* We don't need to disable real-time discard because discard_max_bytes +* will recover after removal of snapshot. +*/ +if (test_opt (sbi,DISCARD ) && !f2fs_hw_support_discard (sbi)) +f2fs_issue_discard_timeout (sbi); +clear_sbi_flag (F2FS_SB (sb),SBI_IS_FREEZING );return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 98/356 i3c: master: add enable(disable) hot join in sys entry
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 317bacf960a4879af22d12175f47d284930b3273 ]
Add hotjoin entry in sys file system allow user enable/disable hotjoin feature.
Add (*enable(disable)_hotjoin)() to i3c_master_controller_ops. Add api i3c_master_enable(disable)_hotjoin();
Stable-dep-of: 25bc99be5fe5 ("i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter")
--- drivers/i3c/master.c | 83 ++++++++++++++++++++++++++++++++++++++ include/linux/i3c/master.h | 5 +++ 2 files changed, 88 insertions(+)
drivers/i3c/master.c +83 -0
@@ -526,6 +526,88 @@ static ssize_t i2c_scl_frequency_show(struct device *dev, }static DEVICE_ATTR_RO (i2c_scl_frequency); +static int i3c_set_hotjoin (struct i3c_master_controller *master,bool enable) +{ +int ret; + +if (!master || !master->ops) +return -EINVAL ; + +if (!master->ops->enable_hotjoin || !master->ops->disable_hotjoin) +return -EINVAL ; + +i3c_bus_normaluse_lock (&master->bus); + +if (enable) + ret = master->ops->enable_hotjoin (master); +else + ret = master->ops->disable_hotjoin (master); + + master->hotjoin = enable; + +i3c_bus_normaluse_unlock (&master->bus); + +return ret; +} + +static ssize_t hotjoin_store (struct device *dev,struct device_attribute *attr, +const char *buf,size_t count) +{ +struct i3c_bus *i3cbus =dev_to_i3cbus (dev); +int ret; +bool res; + +if (!i3cbus->cur_master) +return -EINVAL ; + +if (kstrtobool (buf, &res)) +return -EINVAL ; + + ret =i3c_set_hotjoin (i3cbus->cur_master->common.master, res); +if (ret) +return ret; + +return count; +} + +/* +* i3c_master_enable_hotjoin - Enable hotjoin +* @master: I3C master object +* +* Return: a 0 in case of success, an negative error code otherwise. +*/ +int i3c_master_enable_hotjoin (struct i3c_master_controller *master) +{ +return i3c_set_hotjoin (master, true); +} +EXPORT_SYMBOL_GPL (i3c_master_enable_hotjoin); + +/* +* i3c_master_disable_hotjoin - Disable hotjoin +* @master: I3C master object +* +* Return: a 0 in case of success, an negative error code otherwise. +*/ +int i3c_master_disable_hotjoin (struct i3c_master_controller *master) +{ +return i3c_set_hotjoin (master, false); +} +EXPORT_SYMBOL_GPL (i3c_master_disable_hotjoin); + +static ssize_t hotjoin_show (struct device *dev,struct device_attribute *da,char *buf) +{ +struct i3c_bus *i3cbus =dev_to_i3cbus (dev); +ssize_t ret; + +i3c_bus_normaluse_lock (i3cbus); + ret =sysfs_emit (buf,"%d\n" , i3cbus->cur_master->common.master->hotjoin); +i3c_bus_normaluse_unlock (i3cbus); + +return ret; +} + +static DEVICE_ATTR_RW (hotjoin); +static struct attribute *i3c_masterdev_attrs[] = { &dev_attr_mode.attr, &dev_attr_current_master.attr,
@@ -536,6 +618,7 @@ static struct attribute *i3c_masterdev_attrs[] = { &dev_attr_pid.attr, &dev_attr_dynamic_address.attr, &dev_attr_hdrcap.attr, + &dev_attr_hotjoin.attr,NULL , };ATTRIBUTE_GROUPS (i3c_masterdev);
include/linux/i3c/master.h +5 -0
@@ -452,6 +452,8 @@ struct i3c_master_controller_ops {int (*disable_ibi)(struct i3c_dev_desc *dev);void (*recycle_ibi_slot)(struct i3c_dev_desc *dev,struct i3c_ibi_slot *slot); +int (*enable_hotjoin)(struct i3c_master_controller *master); +int (*disable_hotjoin)(struct i3c_master_controller *master); };/**
@@ -487,6 +489,7 @@ struct i3c_master_controller {const struct i3c_master_controller_ops *ops; unsigned int secondary : 1; unsigned int init_done : 1; + unsigned int hotjoin: 1;struct {struct list_head i3c;struct list_head i2c;
@@ -543,6 +546,8 @@ int i3c_master_register(struct i3c_master_controller *master,const struct i3c_master_controller_ops *ops, bool secondary);void i3c_master_unregister (struct i3c_master_controller *master); +int i3c_master_enable_hotjoin (struct i3c_master_controller *master); +int i3c_master_disable_hotjoin (struct i3c_master_controller *master);/** * i3c_dev_get_master_data() - get master private data attached to an I3C
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 99/356 i3c: master: svc: add hot join support
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 05b26c31a4859af9e75b7de77458e99358364fe1 ]
Add hot join support for svc master controller. Disable hot join by default.
User can use sysfs entry to enable hot join.
Stable-dep-of: 25bc99be5fe5 ("i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter")
--- drivers/i3c/master/svc-i3c-master.c | 61 +++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-)
drivers/i3c/master/svc-i3c-master.c +57 -4
@@ -128,6 +128,9 @@/* This parameter depends on the implementation and may be tuned */ #define SVC_I3C_FIFO_SIZE 16 +#define SVC_I3C_EVENT_IBI BIT(0) +#define SVC_I3C_EVENT_HOTJOIN BIT(1) +struct svc_i3c_cmd {u8 addr;bool rnw;
@@ -178,6 +181,7 @@ struct svc_i3c_regs_save {* @ibi.tbq_slot: To be queued IBI slot * @ibi.lock: IBI lock * @lock: Transfer lock, protect between IBI work thread and callbacks from master +* @enabled_events: Bit masks for enable events (IBI, HotJoin). */ struct svc_i3c_master {struct i3c_master_controller base;
@@ -207,6 +211,7 @@ struct svc_i3c_master {spinlock_t lock; } ibi;struct mutex lock; +int enabled_events; };/**
@@ -221,6 +226,11 @@ struct svc_i3c_i2c_dev_data {struct i3c_generic_ibi_pool *ibi_pool; }; +static inline bool is_events_enabled (struct svc_i3c_master *master,u32 mask) +{ +return !!(master->enabled_events & mask); +} +static bool svc_i3c_master_error (struct svc_i3c_master *master) {u32 mstatus, merrwarn;
@@ -440,13 +450,16 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)switch (ibitype) {case SVC_I3C_MSTATUS_IBITYPE_IBI : dev =svc_i3c_master_dev_from_addr (master, ibiaddr); -if (!dev) +if (!dev || !is_events_enabled (master,SVC_I3C_EVENT_IBI ))svc_i3c_master_nack_ibi (master);else svc_i3c_master_handle_ibi (master, dev);break ;case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN : -svc_i3c_master_ack_ibi (master, false); +if (is_events_enabled (master,SVC_I3C_EVENT_HOTJOIN )) +svc_i3c_master_ack_ibi (master, false); +else +svc_i3c_master_nack_ibi (master);break ;case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST :svc_i3c_master_nack_ibi (master);
@@ -483,7 +496,9 @@ static void svc_i3c_master_ibi_work(struct work_struct *work)svc_i3c_master_emit_stop (master);break ;case SVC_I3C_MSTATUS_IBITYPE_HOT_JOIN : -queue_work (master->base.wq, &master->hj_work); +svc_i3c_master_emit_stop (master); +if (is_events_enabled (master,SVC_I3C_EVENT_HOTJOIN )) +queue_work (master->base.wq, &master->hj_work);break ;case SVC_I3C_MSTATUS_IBITYPE_MASTER_REQUEST :default :
@@ -1520,6 +1535,7 @@ static int svc_i3c_master_enable_ibi(struct i3c_dev_desc *dev)return ret; } + master->enabled_events |=SVC_I3C_EVENT_IBI ;svc_i3c_master_enable_interrupts (master,SVC_I3C_MINT_SLVSTART );return i3c_master_enec_locked (m, dev->info.dyn_addr,I3C_CCC_EVENT_SIR );
@@ -1531,7 +1547,9 @@ static int svc_i3c_master_disable_ibi(struct i3c_dev_desc *dev)struct svc_i3c_master *master =to_svc_i3c_master (m);int ret; -svc_i3c_master_disable_interrupts (master); + master->enabled_events &= ~SVC_I3C_EVENT_IBI ; +if (!master->enabled_events) +svc_i3c_master_disable_interrupts (master); ret =i3c_master_disec_locked (m, dev->info.dyn_addr,I3C_CCC_EVENT_SIR );
@@ -1541,6 +1559,39 @@ static int svc_i3c_master_disable_ibi(struct i3c_dev_desc *dev)return ret; } +static int svc_i3c_master_enable_hotjoin (struct i3c_master_controller *m) +{ +struct svc_i3c_master *master =to_svc_i3c_master (m); +int ret; + + ret =pm_runtime_resume_and_get (master->dev); +if (ret <0 ) { +dev_err (master->dev,"<%s> Cannot get runtime PM.\n" , __func__); +return ret; + } + + master->enabled_events |=SVC_I3C_EVENT_HOTJOIN ; + +svc_i3c_master_enable_interrupts (master,SVC_I3C_MINT_SLVSTART ); + +return 0 ; +} + +static int svc_i3c_master_disable_hotjoin (struct i3c_master_controller *m) +{ +struct svc_i3c_master *master =to_svc_i3c_master (m); + + master->enabled_events &= ~SVC_I3C_EVENT_HOTJOIN ; + +if (!master->enabled_events) +svc_i3c_master_disable_interrupts (master); + +pm_runtime_mark_last_busy (master->dev); +pm_runtime_put_autosuspend (master->dev); + +return 0 ; +} +static void svc_i3c_master_recycle_ibi_slot (struct i3c_dev_desc *dev,struct i3c_ibi_slot *slot) {
@@ -1567,6 +1618,8 @@ static const struct i3c_master_controller_ops svc_i3c_master_ops = { .recycle_ibi_slot = svc_i3c_master_recycle_ibi_slot, .enable_ibi = svc_i3c_master_enable_ibi, .disable_ibi = svc_i3c_master_disable_ibi, + .enable_hotjoin = svc_i3c_master_enable_hotjoin, + .disable_hotjoin = svc_i3c_master_disable_hotjoin, };static int svc_i3c_master_prepare_clks (struct svc_i3c_master *master)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 100/356 i3c: master: fix kernel-doc check warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 34d946b723b53488ab39d8ac540ddf9db255317a ]
Fix warning found by
'scripts/kernel-doc -v -none include/linux/i3c/master.h'
include/linux/i3c/master.h:457: warning: Function parameter or member 'enable_hotjoin' not described in 'i3c_master_controller_ops' include/linux/i3c/master.h:457: warning: Function parameter or member 'disable_hotjoin' not described in 'i3c_master_controller_ops' include/linux/i3c/master.h:499: warning: Function parameter or member 'hotjoin' not described in 'i3c_master_controller'
Stable-dep-of: 25bc99be5fe5 ("i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter")
--- include/linux/i3c/master.h | 3 +++ 1 file changed, 3 insertions(+)
include/linux/i3c/master.h +3 -0
@@ -426,6 +426,8 @@ struct i3c_bus {* for a future IBI * This method is mandatory only if ->request_ibi is not * NULL. +* @enable_hotjoin: enable hot join event detect. +* @disable_hotjoin: disable hot join event detect. */ struct i3c_master_controller_ops {int (*bus_init)(struct i3c_master_controller *master);
@@ -467,6 +469,7 @@ struct i3c_master_controller_ops {* @ops: master operations. See &struct i3c_master_controller_ops * @secondary: true if the master is a secondary master * @init_done: true when the bus initialization is done +* @hotjoin: true if the master support hotjoin * @boardinfo.i3c: list of I3C boardinfo objects * @boardinfo.i2c: list of I2C boardinfo objects * @boardinfo: board-level information attached to devices connected on the bus
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 101/356 i3c: master: support to adjust first broadcast address speed
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Song <[email protected]>
[ Upstream commit aef79e189ba2b32f78bd35daf2c0b41f3868a321 ]
According to I3C spec 6.2 Timing Specification, the Open Drain High Period of SCL Clock timing for first broadcast address should be adjusted to 200ns at least. I3C device working as i2c device will see the broadcast to close its Spike Filter then change to work at I3C mode. After that I3C open drain SCL high level should be adjusted back.
Stable-dep-of: 25bc99be5fe5 ("i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter")
--- drivers/i3c/master.c | 12 ++++++++++++ include/linux/i3c/master.h | 16 ++++++++++++++++ 2 files changed, 28 insertions(+)
drivers/i3c/master.c +12 -0
@@ -1827,6 +1827,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) goto err_bus_cleanup; } +if (master->ops->set_speed) { + ret = master->ops->set_speed (master,I3C_OPEN_DRAIN_SLOW_SPEED ); +if (ret) + goto err_bus_cleanup; + } +/* * Reset all dynamic address that may have been assigned before * (assigned by the bootloader for example).
@@ -1835,6 +1841,12 @@ static int i3c_master_bus_init(struct i3c_master_controller *master)if (ret && ret !=I3C_ERROR_M2 ) goto err_bus_cleanup; +if (master->ops->set_speed) { + master->ops->set_speed (master,I3C_OPEN_DRAIN_NORMAL_SPEED ); +if (ret) + goto err_bus_cleanup; + } +/* Disable all slave events before starting DAA. */ ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR, I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
include/linux/i3c/master.h +16 -0
@@ -269,6 +269,20 @@ enum i3c_bus_mode { I3C_BUS_MODE_MIXED_SLOW, }; +/** +* enum i3c_open_drain_speed - I3C open-drain speed +* @I3C_OPEN_DRAIN_SLOW_SPEED: Slow open-drain speed for sending the first +* broadcast address. The first broadcast address at this speed +* will be visible to all devices on the I3C bus. I3C devices +* working in I2C mode will turn off their spike filter when +* switching into I3C mode. +* @I3C_OPEN_DRAIN_NORMAL_SPEED: Normal open-drain speed in I3C bus mode. +*/ +enum i3c_open_drain_speed { +I3C_OPEN_DRAIN_SLOW_SPEED , +I3C_OPEN_DRAIN_NORMAL_SPEED , +}; +/** * enum i3c_addr_slot_status - I3C address slot status * @I3C_ADDR_SLOT_FREE: address is free
@@ -428,6 +442,7 @@ struct i3c_bus {* NULL. * @enable_hotjoin: enable hot join event detect. * @disable_hotjoin: disable hot join event detect. +* @set_speed: adjust I3C open drain mode timing. */ struct i3c_master_controller_ops {int (*bus_init)(struct i3c_master_controller *master);
@@ -456,6 +471,7 @@ struct i3c_master_controller_ops { struct i3c_ibi_slot *slot);int (*enable_hotjoin)(struct i3c_master_controller *master);int (*disable_hotjoin)(struct i3c_master_controller *master); +int (*set_speed)(struct i3c_master_controller *master,enum i3c_open_drain_speed speed); };/**
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 102/356 i3c: master: svc: use slow speed for first broadcast address
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Song <[email protected]>
[ Upstream commit 20ade67bb1645f5ce8f37fa79ddfebbc5b5b24ef ]
I3C controller should support adjusting open drain timing for the first broadcast address to make I3C device working as a i2c device can see slow broadcast address to close its Spike Filter to change working at i3c mode.
Stable-dep-of: 25bc99be5fe5 ("i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter")
--- drivers/i3c/master/svc-i3c-master.c | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+)
drivers/i3c/master/svc-i3c-master.c +52 -0
@@ -182,6 +182,7 @@ struct svc_i3c_regs_save {* @ibi.lock: IBI lock * @lock: Transfer lock, protect between IBI work thread and callbacks from master * @enabled_events: Bit masks for enable events (IBI, HotJoin). +* @mctrl_config: Configuration value in SVC_I3C_MCTRL for setting speed back. */ struct svc_i3c_master {struct i3c_master_controller base;
@@ -212,6 +213,7 @@ struct svc_i3c_master { } ibi;struct mutex lock;int enabled_events; +u32 mctrl_config; };/**
@@ -529,6 +531,54 @@ static irqreturn_t svc_i3c_master_irq_handler(int irq, void *dev_id)return IRQ_HANDLED ; } +static int svc_i3c_master_set_speed (struct i3c_master_controller *m, +enum i3c_open_drain_speed speed) +{ +struct svc_i3c_master *master =to_svc_i3c_master (m); +struct i3c_bus *bus =i3c_master_get_bus (&master->base); +u32 ppbaud, odbaud, odhpp, mconfig; +unsigned long fclk_rate; +int ret; + + ret =pm_runtime_resume_and_get (master->dev); +if (ret <0 ) { +dev_err (master->dev,"<%s> Cannot get runtime PM.\n" , __func__); +return ret; + } + +switch (speed) { +case I3C_OPEN_DRAIN_SLOW_SPEED : + fclk_rate =clk_get_rate (master->fclk); +if (!fclk_rate) { + ret = -EINVAL ; + goto rpm_out; + } +/* +* Set 50% duty-cycle I2C speed to I3C OPEN-DRAIN mode, so the first +* broadcast address is visible to all I2C/I3C devices on the I3C bus. +* I3C device working as a I2C device will turn off its 50ns Spike +* Filter to change to I3C mode. +*/ + mconfig = master->mctrl_config; + ppbaud =FIELD_GET (GENMASK (11 ,8 ), mconfig); + odhpp =0 ; + odbaud =DIV_ROUND_UP (fclk_rate, bus->scl_rate.i2c * (2 +2 * ppbaud)) -1 ; + mconfig &= ~GENMASK (24 ,16 ); + mconfig |=SVC_I3C_MCONFIG_ODBAUD (odbaud) |SVC_I3C_MCONFIG_ODHPP (odhpp); +writel (mconfig, master->regs +SVC_I3C_MCONFIG ); +break ; +case I3C_OPEN_DRAIN_NORMAL_SPEED : +writel (master->mctrl_config, master->regs +SVC_I3C_MCONFIG ); +break ; + } + +rpm_out: +pm_runtime_mark_last_busy (master->dev); +pm_runtime_put_autosuspend (master->dev); + +return ret; +} +static int svc_i3c_master_bus_init (struct i3c_master_controller *m) {struct svc_i3c_master *master =to_svc_i3c_master (m);
@@ -611,6 +661,7 @@ static int svc_i3c_master_bus_init(struct i3c_master_controller *m)SVC_I3C_MCONFIG_I2CBAUD (i2cbaud);writel (reg, master->regs +SVC_I3C_MCONFIG ); + master->mctrl_config = reg;/* Master core's registration */ ret =i3c_master_get_free_addr (m,0 );if (ret <0 )
@@ -1620,6 +1671,7 @@ static const struct i3c_master_controller_ops svc_i3c_master_ops = { .disable_ibi = svc_i3c_master_disable_ibi, .enable_hotjoin = svc_i3c_master_enable_hotjoin, .disable_hotjoin = svc_i3c_master_disable_hotjoin, + .set_speed = svc_i3c_master_set_speed, };static int svc_i3c_master_prepare_clks (struct svc_i3c_master *master)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 103/356 i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 25bc99be5fe53853053ceeaa328068c49dc1e799 ]
Fix issue where disabling IBI on one device disables the entire IBI interrupt. Modify bit 7:0 of enabled_events to serve as an IBI enable counter, ensuring that the system IBI interrupt is disabled only when all I3C devices have IBI disabled.
--- drivers/i3c/master/svc-i3c-master.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/i3c/master/svc-i3c-master.c +5 -5
@@ -128,8 +128,8 @@/* This parameter depends on the implementation and may be tuned */ #define SVC_I3C_FIFO_SIZE 16 -#define SVC_I3C_EVENT_IBI BIT(0) -#define SVC_I3C_EVENT_HOTJOIN BIT(1) +#define SVC_I3C_EVENT_IBI GENMASK(7, 0) +#define SVC_I3C_EVENT_HOTJOIN BIT(31)struct svc_i3c_cmd {u8 addr;
@@ -212,7 +212,7 @@ struct svc_i3c_master {spinlock_t lock; } ibi;struct mutex lock; -int enabled_events; +u32 enabled_events;u32 mctrl_config; };
@@ -1586,7 +1586,7 @@ static int svc_i3c_master_enable_ibi(struct i3c_dev_desc *dev)return ret; } - master->enabled_events |=SVC_I3C_EVENT_IBI ; + master->enabled_events++;svc_i3c_master_enable_interrupts (master,SVC_I3C_MINT_SLVSTART );return i3c_master_enec_locked (m, dev->info.dyn_addr,I3C_CCC_EVENT_SIR );
@@ -1598,7 +1598,7 @@ static int svc_i3c_master_disable_ibi(struct i3c_dev_desc *dev)struct svc_i3c_master *master =to_svc_i3c_master (m);int ret; - master->enabled_events &= ~SVC_I3C_EVENT_IBI ; + master->enabled_events--;if (!master->enabled_events)svc_i3c_master_disable_interrupts (master);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 104/356 i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 16aed0a6520ba01b7d22c32e193fc1ec674f92d4 ]
Replace the hardcoded value 2, which indicates 2 bits for I3C address status, with the predefined macro I3C_ADDR_SLOT_STATUS_BITS.
Improve maintainability and extensibility of the code.
Stable-dep-of: 851bd21cdb55 ("i3c: master: Fix dynamic address leak when 'assigned-address' is present")
--- drivers/i3c/master.c | 4 ++-- include/linux/i3c/master.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-)
drivers/i3c/master.c +2 -2
@@ -345,7 +345,7 @@ static enum i3c_addr_slot_status i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr) {unsigned long status; -int bitpos = addr *2 ; +int bitpos = addr *I3C_ADDR_SLOT_STATUS_BITS ;if (addr >I2C_MAX_ADDR )return I3C_ADDR_SLOT_RSVD ;
@@ -359,7 +359,7 @@ i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)static void i3c_bus_set_addr_slot_status (struct i3c_bus *bus,u16 addr,enum i3c_addr_slot_status status) { -int bitpos = addr *2 ; +int bitpos = addr *I3C_ADDR_SLOT_STATUS_BITS ;unsigned long *ptr;if (addr >I2C_MAX_ADDR )
include/linux/i3c/master.h +3 -1
@@ -305,6 +305,8 @@ enum i3c_addr_slot_status { I3C_ADDR_SLOT_STATUS_MASK = 3, }; +#define I3C_ADDR_SLOT_STATUS_BITS 2 +/** * struct i3c_bus - I3C bus object * @cur_master: I3C master currently driving the bus. Since I3C is multi-master
@@ -346,7 +348,7 @@ enum i3c_addr_slot_status {struct i3c_bus {struct i3c_dev_desc *cur_master;int id; -unsigned long addrslots[((I2C_MAX_ADDR +1 ) *2 ) /BITS_PER_LONG ]; +unsigned long addrslots[((I2C_MAX_ADDR +1 ) *I3C_ADDR_SLOT_STATUS_BITS ) /BITS_PER_LONG ];enum i3c_bus_mode mode;struct {unsigned long i3c;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 105/356 i3c: master: Extend address status bit to 4 and add I3C_ADDR_SLOT_EXT_DESIRED
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 2f552fa280590e61bd3dbe66a7b54b99caa642a4 ]
Extend the address status bit to 4 and introduce the I3C_ADDR_SLOT_EXT_DESIRED macro to indicate that a device prefers a specific address. This is generally set by the 'assigned-address' in the device tree source (dts) file.
┌────┬─────────────┬───┬─────────┬───┐
│S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐
└────┴─────────────┴───┴─────────┴───┘ │
┌─────────────────────────────────────────┘
│ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
└─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│
└──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘Some master controllers (such as HCI) need to prepare the entire above transaction before sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated before knowing the target device's UID information.
However, some I3C targets may request specific addresses (called as "init_dyn_addr"), which is typically specified by the DT-'s assigned-address property. Lower addresses having higher IBI priority. If it is available, i3c_bus_get_free_addr() preferably return a free address that is not in the list of desired addresses (called as "init_dyn_addr"). This allows the device with the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise, if the "init_dyn_addr" is already in use by another I3C device, the target device will not be able to switch to its desired address.
If the previous step fails, fallback returning one of the remaining unassigned address, regardless of its state in the desired list.
Stable-dep-of: 851bd21cdb55 ("i3c: master: Fix dynamic address leak when 'assigned-address' is present")
--- drivers/i3c/master.c | 65 +++++++++++++++++++++++++++++++------- include/linux/i3c/master.h | 7 ++-- 2 files changed, 59 insertions(+), 13 deletions(-)
drivers/i3c/master.c +54 -11
@@ -342,7 +342,7 @@ struct bus_type i3c_bus_type = { };static enum i3c_addr_slot_status -i3c_bus_get_addr_slot_status (struct i3c_bus *bus,u16 addr) +i3c_bus_get_addr_slot_status_mask (struct i3c_bus *bus,u16 addr,u32 mask) {unsigned long status;int bitpos = addr *I3C_ADDR_SLOT_STATUS_BITS ;
@@ -353,11 +353,17 @@ i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr) status = bus->addrslots[bitpos /BITS_PER_LONG ]; status >>= bitpos %BITS_PER_LONG ; -return status &I3C_ADDR_SLOT_STATUS_MASK ; +return status & mask; } -static void i3c_bus_set_addr_slot_status (struct i3c_bus *bus,u16 addr, -enum i3c_addr_slot_status status) +static enum i3c_addr_slot_status +i3c_bus_get_addr_slot_status (struct i3c_bus *bus,u16 addr) +{ +return i3c_bus_get_addr_slot_status_mask (bus, addr,I3C_ADDR_SLOT_STATUS_MASK ); +} + +static void i3c_bus_set_addr_slot_status_mask (struct i3c_bus *bus,u16 addr, +enum i3c_addr_slot_status status,u32 mask) {int bitpos = addr *I3C_ADDR_SLOT_STATUS_BITS ;unsigned long *ptr;
@@ -366,9 +372,14 @@ static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,return ; ptr = bus->addrslots + (bitpos /BITS_PER_LONG ); - *ptr &= ~((unsigned long )I3C_ADDR_SLOT_STATUS_MASK << - (bitpos %BITS_PER_LONG )); - *ptr |= (unsigned long )status << (bitpos %BITS_PER_LONG ); + *ptr &= ~((unsigned long )mask << (bitpos %BITS_PER_LONG )); + *ptr |= ((unsigned long )status & mask) << (bitpos %BITS_PER_LONG ); +} + +static void i3c_bus_set_addr_slot_status (struct i3c_bus *bus,u16 addr, +enum i3c_addr_slot_status status) +{ +i3c_bus_set_addr_slot_status_mask (bus, addr, status,I3C_ADDR_SLOT_STATUS_MASK ); }static bool i3c_bus_dev_addr_is_avail (struct i3c_bus *bus,u8 addr)
@@ -380,13 +391,44 @@ static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)return status ==I3C_ADDR_SLOT_FREE ; } +/* +* ┌────┬─────────────┬───┬─────────┬───┐ +* │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐ +* └────┴─────────────┴───┴─────────┴───┘ │ +* ┌─────────────────────────────────────────┘ +* │ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐ +* └─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│ +* └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘ +* Some master controllers (such as HCI) need to prepare the entire above transaction before +* sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated +* before knowing the target device's UID information. +* +* However, some I3C targets may request specific addresses (called as "init_dyn_addr"), which is +* typically specified by the DT-'s assigned-address property. Lower addresses having higher IBI +* priority. If it is available, i3c_bus_get_free_addr() preferably return a free address that is +* not in the list of desired addresses (called as "init_dyn_addr"). This allows the device with +* the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise, +* if the "init_dyn_addr" is already in use by another I3C device, the target device will not be +* able to switch to its desired address. +* +* If the previous step fails, fallback returning one of the remaining unassigned address, +* regardless of its state in the desired list. +*/ static int i3c_bus_get_free_addr (struct i3c_bus *bus,u8 start_addr) {enum i3c_addr_slot_status status;u8 addr;for (addr = start_addr; addr <I3C_MAX_ADDR ; addr++) { - status =i3c_bus_get_addr_slot_status (bus, addr); + status =i3c_bus_get_addr_slot_status_mask (bus, addr, +I3C_ADDR_SLOT_EXT_STATUS_MASK ); +if (status ==I3C_ADDR_SLOT_FREE ) +return addr; + } + +for (addr = start_addr; addr <I3C_MAX_ADDR ; addr++) { + status =i3c_bus_get_addr_slot_status_mask (bus, addr, +I3C_ADDR_SLOT_STATUS_MASK );if (status ==I3C_ADDR_SLOT_FREE )return addr; }
@@ -1877,9 +1919,10 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) goto err_rstdaa; } -i3c_bus_set_addr_slot_status (&master->bus, - i3cboardinfo->init_dyn_addr, -I3C_ADDR_SLOT_I3C_DEV ); +i3c_bus_set_addr_slot_status_mask (&master->bus, + i3cboardinfo->init_dyn_addr, +I3C_ADDR_SLOT_I3C_DEV |I3C_ADDR_SLOT_EXT_DESIRED , +I3C_ADDR_SLOT_EXT_STATUS_MASK );/* * Only try to create/attach devices that have a static
include/linux/i3c/master.h +5 -2
@@ -290,7 +290,8 @@ enum i3c_open_drain_speed {* @I3C_ADDR_SLOT_I2C_DEV: address is assigned to an I2C device * @I3C_ADDR_SLOT_I3C_DEV: address is assigned to an I3C device * @I3C_ADDR_SLOT_STATUS_MASK: address slot mask -* +* @I3C_ADDR_SLOT_EXT_DESIRED: the bitmask represents addresses that are preferred by some devices, +* such as the "assigned-address" property in a device tree source. * On an I3C bus, addresses are assigned dynamically, and we need to know which * addresses are free to use and which ones are already assigned. *
@@ -303,9 +304,11 @@ enum i3c_addr_slot_status {I3C_ADDR_SLOT_I2C_DEV ,I3C_ADDR_SLOT_I3C_DEV ,I3C_ADDR_SLOT_STATUS_MASK =3 , +I3C_ADDR_SLOT_EXT_STATUS_MASK =7 , + I3C_ADDR_SLOT_EXT_DESIRED = BIT(2), }; -#define I3C_ADDR_SLOT_STATUS_BITS 2 +#define I3C_ADDR_SLOT_STATUS_BITS 4/** * struct i3c_bus - I3C bus object
Signature · 1 line
2.43.0