5.12.13-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 5.12.13-rc1 review
This is the start of the stable review cycle for the 5.12.13 release. There are 178 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 23 Jun 2021 15:48:46 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.12.13-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.12.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.12.13-rc1
Peter Chen <[email protected]>
usb: dwc3: core: fix kernel panic when do reboot
Jack Pham <[email protected]>
usb: dwc3: debugfs: Add and remove endpoint dirs dynamically
Arnaldo Carvalho de Melo <[email protected]>
perf beauty: Update copy of linux/socket.h with the kernel sources
Arnaldo Carvalho de Melo <[email protected]>
tools headers UAPI: Sync linux/in.h copy with the kernel sources
Fugang Duan <[email protected]>
net: fec_ptp: add clock rate zero check
Joakim Zhang <[email protected]>
net: stmmac: disable clocks in stmmac_remove_config_dt()
Andrew Morton <[email protected]>
mm/slub.c: include swab.h
Kees Cook <[email protected]>
mm/slub: actually fix freelist pointer vs redzoning
Kees Cook <[email protected]>
mm/slub: fix redzoning for small allocations
Kees Cook <[email protected]>
mm/slub: clarify verification reporting
Mike Kravetz <[email protected]>
mm/hugetlb: expand restore_reserve_on_error functionality
Peter Xu <[email protected]>
mm/swap: fix pte_same_as_swp() not removing uffd-wp bit when compare
Naoya Horiguchi <[email protected]>
mm,hwpoison: fix race with hugetlb page allocation
Nikolay Aleksandrov <[email protected]>
net: bridge: fix vlan tunnel dst refcnt when egressing
Nikolay Aleksandrov <[email protected]>
net: bridge: fix vlan tunnel dst null pointer dereference
Esben Haabendal <[email protected]>
net: ll_temac: Fix TX BD buffer overwrite
Esben Haabendal <[email protected]>
net: ll_temac: Make sure to free skb when it is completely used
Yifan Zhang <[email protected]>
drm/amdgpu/gfx9: fix the doorbell missing when in CGPG issue.
Yifan Zhang <[email protected]>
drm/amdgpu/gfx10: enlarge CP_MEC_DOORBELL_RANGE_UPPER to cover full doorbell.
Avraham Stern <[email protected]>
cfg80211: avoid double free of PMSR request
Johannes Berg <[email protected]>
cfg80211: make certificate generation more robust
Felix Fietkau <[email protected]>
mac80211: minstrel_ht: fix sample time check
Johannes Berg <[email protected]>
mac80211: move interface shutdown out of wiphy lock
Johannes Berg <[email protected]>
cfg80211: shut down interfaces on failed resume
Johannes Berg <[email protected]>
cfg80211: fix phy80211 symlink creation
Johannes Berg <[email protected]>
mac80211: fix 'reset' debugfs locking
Mathy Vanhoef <[email protected]>
mac80211: Fix NULL ptr deref for injected rate info
Johannes Berg <[email protected]>
mac80211: fix deadlock in AP/VLAN handling
Bumyong Lee <[email protected]>
dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc
Pingfan Liu <[email protected]>
crash_core, vmcoreinfo: append 'SECTION_SIZE_BITS' to vmcoreinfo
Tor Vic <[email protected]>
Makefile: lto: Pass -warn-stack-size only on LLD < 13.0.0
Athira Rajeev <[email protected]>
powerpc/perf: Fix crash in perf_instruction_pointer() when ppmu is not set
Thomas Gleixner <[email protected]>
x86/fpu: Reset state for all signal restore failures
Andy Lutomirski <[email protected]>
x86/fpu: Invalidate FPU state after a failed XRSTOR from a user buffer
Thomas Gleixner <[email protected]>
x86/fpu: Prevent state corruption in __fpu__restore_sig()
Thomas Gleixner <[email protected]>
x86/pkru: Write hardware init value to PKRU when xstate is init
Tom Lendacky <[email protected]>
x86/ioremap: Map EFI-reserved memory as encrypted for SEV
Thomas Gleixner <[email protected]>
x86/process: Check PF_KTHREAD and not current->mm for kernel threads
Fan Du <[email protected]>
x86/mm: Avoid truncating memblocks for SGX memory
Vineet Gupta <[email protected]>
ARCv2: save ABI registers across signal handling
Harald Freudenberger <[email protected]>
s390/ap: Fix hanging ioctl caused by wrong msg counter
Alexander Gordeev <[email protected]>
s390/mcck: fix calculation of SIE critical section size
Wanpeng Li <[email protected]>
KVM: X86: Fix x86_emulator slab cache leak
Sean Christopherson <[email protected]>
KVM: x86/mmu: Calculate and check "full" mmu_role for nested MMU
Sean Christopherson <[email protected]>
KVM: x86: Immediately reset the MMU context when the SMM flag is cleared
Alexander Gordeev <[email protected]>
s390/mcck: fix invalid KVM guest condition check
Naohiro Aota <[email protected]>
btrfs: zoned: fix negative space_info->bytes_readonly
Chiqijun <[email protected]>
PCI: Work around Huawei Intelligent NIC VF FLR erratum
Sriharsha Basavapatna <[email protected]>
PCI: Add ACS quirk for Broadcom BCM57414 NIC
Pali Rohár <[email protected]>
PCI: aardvark: Fix kernel panic during PIO transfer
Evan Quan <[email protected]>
PCI: Mark AMD Navi14 GPU ATS as broken
Shanker Donthineni <[email protected]>
PCI: Mark some NVIDIA GPUs to avoid bus reset
Antti Järvinen <[email protected]>
PCI: Mark TI C667X to avoid bus reset
Steven Rostedt (VMware) <[email protected]>
tracing: Do no increment trace_clock_global() by one
Steven Rostedt (VMware) <[email protected]>
tracing: Do not stop recording comms if the trace file is being read
Steven Rostedt (VMware) <[email protected]>
tracing: Do not stop recording cmdlines when tracing is off
Breno Lima <[email protected]>
usb: chipidea: imx: Fix Battery Charger 1.2 CDP detection
Andrew Lunn <[email protected]>
usb: core: hub: Disable autosuspend for Cypress CY7C65632
Pavel Skripkin <[email protected]>
can: mcba_usb: fix memory leak in mcba_usb
Oleksij Rempel <[email protected]>
can: j1939: fix Use-after-Free, hold skb ref while in use
Tetsuo Handa <[email protected]>
can: bcm/raw/isotp: use per module netdevice notifier
Norbert Slusarek <[email protected]>
can: bcm: fix infoleak in struct bcm_msg_head
Daniel Borkmann <[email protected]>
bpf: Do not mark insn as seen under speculative path verification
Daniel Borkmann <[email protected]>
bpf: Inherit expanded/patched seen count from old aux data
John Garry <[email protected]>
perf metricgroup: Return error code from metricgroup__add_metric_sys_event_iter()
John Garry <[email protected]>
perf metricgroup: Fix find_evsel_group() event selector
Odin Ugedal <[email protected]>
sched/fair: Correctly insert cfs_rq's to list on unthrottle
Marc Zyngier <[email protected]>
irqchip/gic-v3: Workaround inconsistent PMR setting on NMI entry
Feng Tang <[email protected]>
mm: relocate 'write_protect_seq' in struct mm_struct
Jisheng Zhang <[email protected]>
riscv: code patching only works on !XIP_KERNEL
Riwen Lu <[email protected]>
hwmon: (scpi-hwmon) shows the negative temperature properly
Chen Li <[email protected]>
radeon: use memcpy_to/fromio for UVD fw upload
Srinivasa Rao Mandadapu <[email protected]>
ASoC: qcom: lpass-cpu: Fix pop noise during audio capture begin
Saravana Kannan <[email protected]>
drm/sun4i: dw-hdmi: Make HDMI PHY into a platform device
Sergio Paracuellos <[email protected]>
pinctrl: ralink: rt2880: avoid to error in calls is pin is already enabled
Oder Chiou <[email protected]>
ASoC: rt5682: Fix the fast discharge for headset unplugging in soundwire mode
Axel Lin <[email protected]>
regulator: rt4801: Fix NULL pointer dereference if priv->enable_gpios is NULL
Patrice Chotard <[email protected]>
spi: stm32-qspi: Always wait BUSY bit to be cleared in stm32_qspi_wait_cmd()
Axel Lin <[email protected]>
regulator: hi6421v600: Fix .vsel_mask setting
Richard Weinberger <[email protected]>
ASoC: tas2562: Fix TDM_CFG0_SAMPRATE values
Vincent Guittot <[email protected]>
sched/pelt: Ensure that *_sum is always synced with *_avg
zpershuai <[email protected]>
spi: spi-zynq-qspi: Fix some wrong goto jumps & missing error code
ChiYuan Huang <[email protected]>
regulator: rtmv20: Fix to make regcache value first reading back from HW
Axel Lin <[email protected]>
regulator: mt6315: Fix function prototype for mt6315_map_mode
Nicolas Cavallari <[email protected]>
ASoC: fsl-asoc-card: Set .owner attribute when registering card.
Tiezhu Yang <[email protected]>
phy: phy-mtk-tphy: Fix some resource leaks in mtk_phy_init()
Jack Yu <[email protected]>
ASoC: rt5659: Fix the lost powers for the HDA header
Til Jasper Ullrich <[email protected]>
platform/x86: thinkpad_acpi: Add X1 Carbon Gen 9 second fan support
Axel Lin <[email protected]>
regulator: bd70528: Fix off-by-one for buck123 .n_voltages setting
Dmitry Osipenko <[email protected]>
regulator: max77620: Silence deferred probe error
Axel Lin <[email protected]>
regulator: cros-ec: Fix error code in dev_err message
Pavel Skripkin <[email protected]>
net: ethernet: fix potential use-after-free in ec_bhf_remove
Toke Høiland-Jørgensen <[email protected]>
icmp: don't send out ICMP messages with a source address of 0.0.0.0
Somnath Kotur <[email protected]>
bnxt_en: Call bnxt_ethtool_free() in bnxt_init_one() error path
Rukhsana Ansari <[email protected]>
bnxt_en: Fix TQM fastpath ring backing store computation
Michael Chan <[email protected]>
bnxt_en: Rediscover PHY capabilities after firmware reset
Pavel Machek <[email protected]>
cxgb4: fix wrong shift.
Linyu Yuan <[email protected]>
net: cdc_eem: fix tx fixup skb leak
Pavel Skripkin <[email protected]>
net: hamradio: fix memory leak in mkiss_close
Christophe JAILLET <[email protected]>
be2net: Fix an error handling path in 'be_probe()'
Aya Levin <[email protected]>
net/mlx5: Reset mkey index on creation
Dmytro Linkin <[email protected]>
net/mlx5e: Don't create devices during unload flow
Alex Vesker <[email protected]>
net/mlx5: DR, Fix STEv1 incorrect L3 decapsulation padding
Parav Pandit <[email protected]>
net/mlx5: SF_DEV, remove SF device on invalid state
Parav Pandit <[email protected]>
net/mlx5: E-Switch, Allow setting GUID for host PF vport
Parav Pandit <[email protected]>
net/mlx5: E-Switch, Read PF mac address
Leon Romanovsky <[email protected]>
net/mlx5: Check that driver was probed prior attaching the device
Leon Romanovsky <[email protected]>
net/mlx5: Fix error path for set HCA defaults
Eric Dumazet <[email protected]>
net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock
Chengyang Fan <[email protected]>
net: ipv4: fix memory leak in ip_mc_add1_src
Joakim Zhang <[email protected]>
net: fec_ptp: fix issue caused by refactor the fec_devtype
Dongliang Mu <[email protected]>
net: usb: fix possible use-after-free in smsc75xx_bind
Aleksander Jan Bajkowski <[email protected]>
lantiq: net: fix duplicated skb in rx descriptor ring
Maciej Żenczykowski <[email protected]>
net: cdc_ncm: switch to eth%d interface naming
Jakub Kicinski <[email protected]>
ptp: improve max_adj check against unreasonable values
Subash Abhinov Kasiviswanathan <[email protected]>
net: mhi_net: Update the transmit handler prototype
Daniel Borkmann <[email protected]>
bpf: Fix leakage under speculation on mispredicted branches
Pavel Skripkin <[email protected]>
net: qrtr: fix OOB Read in qrtr_endpoint_post
David Ahern <[email protected]>
ipv4: Fix device used for dst_alloc with local routes
Rahul Lakkireddy <[email protected]>
cxgb4: fix wrong ethtool n-tuple rule lookup
Christophe JAILLET <[email protected]>
netxen_nic: Fix an error handling path in 'netxen_nic_probe()'
Christophe JAILLET <[email protected]>
qlcnic: Fix an error handling path in 'qlcnic_probe()'
Jakub Kicinski <[email protected]>
ethtool: strset: fix message length calculation
Alex Elder <[email protected]>
net: qualcomm: rmnet: don't over-count statistics
Changbin Du <[email protected]>
net: make get_net_ns return error if NET_NS is disabled
Jisheng Zhang <[email protected]>
net: stmmac: dwmac1000: Fix extended MAC address registers definition
Rahul Lakkireddy <[email protected]>
cxgb4: halt chip before flashing PHY firmware image
Rahul Lakkireddy <[email protected]>
cxgb4: fix sleep in atomic when flashing PHY firmware
Rahul Lakkireddy <[email protected]>
cxgb4: fix endianness when flashing boot image
Christophe JAILLET <[email protected]>
alx: Fix an error handling path in 'alx_probe()'
Paolo Abeni <[email protected]>
mptcp: fix soft lookup in subflow_error_report()
Paolo Abeni <[email protected]>
selftests: mptcp: enable syncookie only in absence of reorders
Paolo Abeni <[email protected]>
mptcp: do not warn on bad input from the network
Paolo Abeni <[email protected]>
mptcp: wake-up readers only for in sequence data
Paolo Abeni <[email protected]>
mptcp: try harder to borrow memory from subflow under pressure
Maxim Mikityanskiy <[email protected]>
sch_cake: Fix out of bounds when parsing TCP options and header
Maxim Mikityanskiy <[email protected]>
mptcp: Fix out of bounds when parsing TCP options
Maxim Mikityanskiy <[email protected]>
netfilter: synproxy: Fix out of bounds when parsing TCP options
Willem de Bruijn <[email protected]>
skbuff: fix incorrect msg_zerocopy copy notifications
Aya Levin <[email protected]>
net/mlx5e: Block offload of outer header csum for GRE tunnel
Aya Levin <[email protected]>
net/mlx5e: Block offload of outer header csum for UDP tunnels
Shay Drory <[email protected]>
Revert "net/mlx5: Arm only EQs with EQEs"
Maor Gottlieb <[email protected]>
net/mlx5: DR, Don't use SW steering when RoCE is not supported
Maor Gottlieb <[email protected]>
net/mlx5: Consider RoCE cap before init RDMA resources
Dima Chumak <[email protected]>
net/mlx5e: Fix page reclaim for dead peer hairpin
Huy Nguyen <[email protected]>
net/mlx5e: Remove dependency in IPsec initialization flows
Vlad Buslov <[email protected]>
net/mlx5e: Fix use-after-free of encap entry in neigh update handler
Marcelo Ricardo Leitner <[email protected]>
net/sched: act_ct: handle DNAT tuple collision
Ido Schimmel <[email protected]>
rtnetlink: Fix regression in bridge VLAN configuration
Paolo Abeni <[email protected]>
udp: fix race between close() and udp_abort()
Maciej Fijalkowski <[email protected]>
ice: parameterize functions responsible for Tx ring management
Maciej Fijalkowski <[email protected]>
ice: add ndo_bpf callback for safe mode netdev ops
Florian Westphal <[email protected]>
netfilter: nft_fib_ipv6: skip ipv6 packets from any to link-local
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: initialize set before expression setup
Aleksander Jan Bajkowski <[email protected]>
net: lantiq: disable interrupt before sheduling NAPI
Shay Agroskin <[email protected]>
net: ena: fix DMA mapping function issues in XDP
Vladimir Oltean <[email protected]>
net: dsa: felix: re-enable TX flow control in ocelot_port_flush()
Pavel Skripkin <[email protected]>
net: rds: fix memory leak in rds_recvmsg
Nicolas Dichtel <[email protected]>
vrf: fix maximum MTU
Nanyong Sun <[email protected]>
net: ipv4: fix memory leak in netlbl_cipsov4_add_std
Kev Jackson <[email protected]>
libbpf: Fixes incorrect rx_ring_setup_done
Mykola Kostenok <[email protected]>
mlxsw: core: Set thermal zone polling delay argument to real value at init
Petr Machata <[email protected]>
mlxsw: reg: Spectrum-3: Enforce lowest max-shaper burst size of 11
Du Cheng <[email protected]>
mac80211: fix skb length check in ieee80211_scan_rx()
Johannes Berg <[email protected]>
staging: rtl8723bs: fix monitor netdev register/unregister
Sven Eckelmann <[email protected]>
batman-adv: Avoid WARN_ON timing related checks
Matthew Bobrowski <[email protected]>
fanotify: fix copy_event_to_user() fid error clean up
Jim Mattson <[email protected]>
kvm: LAPIC: Restore guard to prevent illegal APIC register access
yangerkun <[email protected]>
mm/memory-failure: make sure wait for page writeback in memory_failure
Dan Carpenter <[email protected]>
afs: Fix an IS_ERR() vs NULL check
Yang Yingliang <[email protected]>
dmaengine: stedma40: add missing iounmap() on error in d40_probe()
Randy Dunlap <[email protected]>
dmaengine: SF_PDMA depends on HAS_IOMEM
Randy Dunlap <[email protected]>
dmaengine: QCOM_HIDMA_MGMT depends on HAS_IOMEM
Randy Dunlap <[email protected]>
dmaengine: ALTERA_MSGDMA depends on HAS_IOMEM
Quanyang Wang <[email protected]>
dmaengine: xilinx: dpdma: initialize registers before request_irq
Zhen Lei <[email protected]>
dmaengine: fsl-dpaa2-qdma: Fix error return code in two functions
Dave Jiang <[email protected]>
dmaengine: idxd: add missing dsa driver unregister
Dave Jiang <[email protected]>
dmaengine: idxd: add engine 'struct device' missing bus type assignment
-------------
Diffstat:
Documentation/vm/slub.rst | 10 +- Makefile | 9 +- arch/arc/include/uapi/asm/sigcontext.h | 1 + arch/arc/kernel/signal.c | 43 +++++++ arch/powerpc/perf/core-book3s.c | 2 +- arch/riscv/Kconfig | 18 +-- arch/s390/kernel/entry.S | 4 +- arch/x86/include/asm/fpu/internal.h | 13 +- arch/x86/kernel/fpu/signal.c | 54 ++++++--- arch/x86/kvm/lapic.c | 3 + arch/x86/kvm/mmu/mmu.c | 26 +++- arch/x86/kvm/x86.c | 6 +- arch/x86/mm/ioremap.c | 4 +- arch/x86/mm/numa.c | 8 +- drivers/dma/Kconfig | 1 + drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c | 3 + drivers/dma/idxd/init.c | 2 + drivers/dma/pl330.c | 6 +- drivers/dma/qcom/Kconfig | 1 + drivers/dma/sf-pdma/Kconfig | 1 + drivers/dma/ste_dma40.c | 3 + drivers/dma/xilinx/xilinx_dpdma.c | 24 +++- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 +- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 6 +- drivers/gpu/drm/radeon/radeon_uvd.c | 4 +- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 31 ++++- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 5 +- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 41 ++++++- drivers/hwmon/scpi-hwmon.c | 9 ++ drivers/irqchip/irq-gic-v3.c | 36 +++++- drivers/net/can/usb/mcba_usb.c | 17 ++- drivers/net/ethernet/amazon/ena/ena_netdev.c | 54 +++++---- drivers/net/ethernet/atheros/alx/main.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 8 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 48 ++++++-- drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 2 +- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 - drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 46 ++++--- drivers/net/ethernet/ec_bhf.c | 4 +- drivers/net/ethernet/emulex/benet/be_main.c | 1 + drivers/net/ethernet/freescale/fec_ptp.c | 8 +- drivers/net/ethernet/intel/ice/ice_lib.c | 18 +-- drivers/net/ethernet/intel/ice/ice_main.c | 15 +++ drivers/net/ethernet/lantiq_xrx200.c | 5 +- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 19 +++ .../net/ethernet/mellanox/mlx5/core/en/rep/neigh.c | 15 +-- .../net/ethernet/mellanox/mlx5/core/en/rep/tc.c | 6 +- .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 33 ++++- .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 - drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 19 +-- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 3 + drivers/net/ethernet/mellanox/mlx5/core/eq.c | 6 +- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 6 + drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 +- drivers/net/ethernet/mellanox/mlx5/core/mr.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 3 + .../net/ethernet/mellanox/mlx5/core/sf/dev/dev.c | 1 + .../mellanox/mlx5/core/steering/dr_ste_v1.c | 26 ++-- .../ethernet/mellanox/mlx5/core/steering/mlx5dr.h | 9 +- drivers/net/ethernet/mellanox/mlx5/core/transobj.c | 30 ++++- drivers/net/ethernet/mellanox/mlx5/core/vport.c | 2 - drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 6 +- drivers/net/ethernet/mellanox/mlxsw/reg.h | 2 +- drivers/net/ethernet/mscc/ocelot.c | 5 + .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 + drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 + drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 18 +-- drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 8 +- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 2 + drivers/net/ethernet/xilinx/ll_temac_main.c | 8 +- drivers/net/hamradio/mkiss.c | 1 + drivers/net/mhi/net.c | 2 +- drivers/net/usb/cdc_eem.c | 2 +- drivers/net/usb/cdc_ncm.c | 2 +- drivers/net/usb/smsc75xx.c | 10 +- drivers/net/vrf.c | 6 +- drivers/pci/controller/pci-aardvark.c | 49 ++++++-- drivers/pci/quirks.c | 93 +++++++++++++- drivers/phy/mediatek/phy-mtk-tphy.c | 2 + drivers/pinctrl/ralink/pinctrl-rt2880.c | 2 +- drivers/platform/x86/thinkpad_acpi.c | 1 + drivers/ptp/ptp_clock.c | 6 +- drivers/regulator/cros-ec-regulator.c | 3 +- drivers/regulator/max77620-regulator.c | 10 +- drivers/regulator/mt6315-regulator.c | 2 +- drivers/regulator/rt4801-regulator.c | 4 +- drivers/regulator/rtmv20-regulator.c | 2 + drivers/s390/crypto/ap_queue.c | 11 +- drivers/spi/spi-stm32-qspi.c | 5 +- drivers/spi/spi-zynq-qspi.c | 7 +- drivers/staging/hikey9xx/hi6421v600-regulator.c | 2 +- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 4 +- drivers/usb/chipidea/usbmisc_imx.c | 16 ++- drivers/usb/core/hub.c | 7 ++ drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/debug.h | 3 + drivers/usb/dwc3/debugfs.c | 21 +--- drivers/usb/dwc3/gadget.c | 3 + fs/afs/main.c | 4 +- fs/btrfs/block-group.c | 8 +- fs/hugetlbfs/inode.c | 1 + fs/notify/fanotify/fanotify_user.c | 4 +- include/linux/hugetlb.h | 8 ++ include/linux/mfd/rohm-bd70528.h | 4 +- include/linux/mlx5/driver.h | 4 + include/linux/mlx5/transobj.h | 1 + include/linux/mm_types.h | 27 +++-- include/linux/ptp_clock_kernel.h | 2 +- include/linux/socket.h | 2 - include/linux/swapops.h | 15 ++- include/net/mac80211.h | 7 +- include/net/net_namespace.h | 7 ++ include/uapi/linux/in.h | 3 + kernel/bpf/verifier.c | 68 +++++++++-- kernel/crash_core.c | 1 + kernel/sched/fair.c | 54 +++++---- kernel/trace/trace.c | 11 -- kernel/trace/trace_clock.c | 6 +- mm/hugetlb.c | 135 +++++++++++++++++---- mm/memory-failure.c | 36 +++++- mm/slab_common.c | 3 +- mm/slub.c | 37 +++--- mm/swapfile.c | 2 +- net/batman-adv/bat_iv_ogm.c | 4 +- net/bridge/br_private.h | 4 +- net/bridge/br_vlan_tunnel.c | 38 +++--- net/can/bcm.c | 62 ++++++++-- net/can/isotp.c | 61 ++++++++-- net/can/j1939/transport.c | 54 ++++++--- net/can/raw.c | 62 +++++++--- net/core/net_namespace.c | 12 ++ net/core/rtnetlink.c | 8 +- net/core/skbuff.c | 4 +- net/ethtool/strset.c | 2 + net/ipv4/cipso_ipv4.c | 1 + net/ipv4/icmp.c | 7 ++ net/ipv4/igmp.c | 1 + net/ipv4/route.c | 15 ++- net/ipv4/udp.c | 10 ++ net/ipv6/netfilter/nft_fib_ipv6.c | 22 +++- net/ipv6/udp.c | 3 + net/mac80211/debugfs.c | 11 +- net/mac80211/iface.c | 19 +-- net/mac80211/main.c | 7 +- net/mac80211/rc80211_minstrel_ht.c | 2 +- net/mac80211/scan.c | 21 +++- net/mac80211/tx.c | 52 +++++--- net/mac80211/util.c | 2 - net/mptcp/options.c | 2 + net/mptcp/protocol.c | 52 ++++---- net/mptcp/protocol.h | 1 - net/mptcp/subflow.c | 108 ++++++++--------- net/netfilter/nf_synproxy_core.c | 5 + net/netfilter/nf_tables_api.c | 83 ++++++------- net/qrtr/qrtr.c | 2 +- net/rds/recv.c | 2 +- net/sched/act_ct.c | 21 ++-- net/sched/sch_cake.c | 6 +- net/socket.c | 13 -- net/unix/af_unix.c | 7 +- net/wireless/Makefile | 2 +- net/wireless/core.c | 13 +- net/wireless/pmsr.c | 16 ++- net/wireless/sysfs.c | 4 + sound/soc/codecs/rt5659.c | 26 +++- sound/soc/codecs/rt5682-sdw.c | 3 +- sound/soc/codecs/tas2562.h | 14 +-- sound/soc/fsl/fsl-asoc-card.c | 1 + sound/soc/qcom/lpass-cpu.c | 79 ++++++++++++ sound/soc/qcom/lpass.h | 4 + tools/include/uapi/linux/in.h | 3 + tools/lib/bpf/xsk.c | 2 +- tools/perf/trace/beauty/include/linux/socket.h | 2 - tools/perf/util/metricgroup.c | 14 ++- tools/testing/selftests/net/fib_tests.sh | 25 ++++ tools/testing/selftests/net/mptcp/mptcp_connect.sh | 11 +- 177 files changed, 1880 insertions(+), 702 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/178 dmaengine: idxd: add engine struct device missing bus type assignment
From: Dave Jiang <[email protected]>
[ Upstream commit 1c4841ccbd2b185587010d6178aac11953f61d4c ]
engine 'struct device' setup is missing assigning the bus type. Add it to dsa_bus_type.
--- drivers/dma/idxd/init.c | 1 + 1 file changed, 1 insertion(+)
drivers/dma/idxd/init.c +1 -0
@@ -218,6 +218,7 @@ static int idxd_setup_engines(struct idxd_device *idxd) engine->idxd = idxd;device_initialize (&engine->conf_dev); engine->conf_dev.parent = &idxd->conf_dev; + engine->conf_dev.bus = &dsa_bus_type; engine->conf_dev.type = &idxd_engine_device_type; rc =dev_set_name (&engine->conf_dev,"engine%d.%d" , idxd->id, engine->id);if (rc <0 ) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 2/178 dmaengine: idxd: add missing dsa driver unregister
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
[ Upstream commit 077cdb355b3d8ee0f258856962e6dac06e744401 ]
The idxd_unregister_driver() has never been called for the idxd driver upon removal. Add fix to call unregister driver on module removal.
--- drivers/dma/idxd/init.c | 1 + 1 file changed, 1 insertion(+)
drivers/dma/idxd/init.c +1 -0
@@ -719,6 +719,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { +idxd_unregister_driver ();pci_unregister_driver (&idxd_pci_driver);idxd_cdev_remove ();idxd_unregister_bus_type ();
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 3/178 dmaengine: fsl-dpaa2-qdma: Fix error return code in two functions
In reply to Greg Kroah-HartmanFrom: Zhen Lei <[email protected]>
[ Upstream commit 17866bc6b2ae1c3075c9fe7bcbeb8ea50eb4c3fc ]
Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in the function where it is.
--- drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +3 -0
@@ -332,6 +332,7 @@ static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) }if (priv->dpdmai_attr.version.major >DPDMAI_VER_MAJOR ) { + err = -EINVAL ; dev_err(dev, "DPDMAI major version mismatch\n" "Found %u.%u, supported version is %u.%u\n", priv->dpdmai_attr.version.major,
@@ -341,6 +342,7 @@ static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) }if (priv->dpdmai_attr.version.minor >DPDMAI_VER_MINOR ) { + err = -EINVAL ; dev_err(dev, "DPDMAI minor version mismatch\n" "Found %u.%u, supported version is %u.%u\n", priv->dpdmai_attr.version.major,
@@ -475,6 +477,7 @@ static int __cold dpaa2_qdma_dpio_setup(struct dpaa2_qdma_priv *priv) ppriv->store =dpaa2_io_store_create (DPAA2_QDMA_STORE_SIZE , dev);if (!ppriv->store) { + err = -ENOMEM ;dev_err (dev,"dpaa2_io_store_create() failed\n" ); goto err_store; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 4/178 dmaengine: xilinx: dpdma: initialize registers before request_irq
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
[ Upstream commit 538ea65a9fd1194352a41313bff876b74b5d90c5 ]
In some scenarios (kdump), dpdma hardware irqs has been enabled when calling request_irq in probe function, and then the dpdma irq handler xilinx_dpdma_irq_handler is invoked to access xdev->chan[i]. But at this moment xdev->chan[i] hasn't been initialized.
We should ensure the dpdma controller to be in a consistent and clean state before further initialization. So add dpdma_hw_init() to do this.
Furthermore, in xilinx_dpdma_disable_irq, disable all interrupts instead of error interrupts.
This patch is to fix the kdump kernel crash as below:
[ 3.696128] Unable to handle kernel NULL pointer dereference at virtual address 000000000000012c [ 3.696710] xilinx-zynqmp-dpdma fd4c0000.dma-controller: Xilinx DPDMA engine is probed [ 3.704900] Mem abort info: [ 3.704902] ESR = 0x96000005 [ 3.704905] EC = 0x25: DABT (current EL), IL = 32 bits [ 3.704907] SET = 0, FnV = 0 [ 3.704912] EA = 0, S1PTW = 0 [ 3.713800] ahci-ceva fd0c0000.ahci: supply ahci not found, using dummy regulator [ 3.715585] Data abort info: [ 3.715587] ISV = 0, ISS = 0x00000005 [ 3.715589] CM = 0, WnR = 0 [ 3.715592] [000000000000012c] user address but active_mm is swapper [ 3.715596] Internal error: Oops: 96000005 [#1] SMP [ 3.715599] Modules linked in: [ 3.715608] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.0-12170-g60894882155f-dirty #77 [ 3.723937] Hardware name: ZynqMP ZCU102 Rev1.0 (DT) [ 3.723942] pstate: 80000085 (Nzcv daIf -PAN -UAO -TCO BTYPE=--) [ 3.723956] pc : xilinx_dpdma_irq_handler+0x418/0x560 [ 3.793049] lr : xilinx_dpdma_irq_handler+0x3d8/0x560 [ 3.798089] sp : ffffffc01186bdf0 [ 3.801388] x29: ffffffc01186bdf0 x28: ffffffc011836f28 [ 3.806692] x27: ffffff8023e0ac80 x26: 0000000000000080 [ 3.811996] x25: 0000000008000408 x24: 0000000000000003 [ 3.817300] x23: ffffffc01186be70 x22: ffffffc011291740 [ 3.822604] x21: 0000000000000000 x20: 0000000008000408 [ 3.827908] x19: 0000000000000000 x18: 0000000000000010 [ 3.833212] x17: 0000000000000000 x16: 0000000000000000 [ 3.838516] x15: 0000000000000000 x14: ffffffc011291740 [ 3.843820] x13: ffffffc02eb4d000 x12: 0000000034d4d91d [ 3.849124] x11: 0000000000000040 x10: ffffffc0112d2d48 [ 3.854428] x9 : ffffffc0112d2d40 x8 : ffffff8021c00268 [ 3.859732] x7 : 0000000000000000 x6 : ffffffc011836000 [ 3.865036] x5 : 0000000000000003 x4 : 0000000000000000 [ 3.870340] x3 : 0000000000000001 x2 : 0000000000000000 [ 3.875644] x1 : 0000000000000000 x0 : 000000000000012c [ 3.880948] Call trace: [ 3.883382] xilinx_dpdma_irq_handler+0x418/0x560 [ 3.888079] __handle_irq_event_percpu+0x5c/0x178 [ 3.892774] handle_irq_event_percpu+0x34/0x98 [ 3.897210] handle_irq_event+0x44/0xb8 [ 3.901030] handle_fasteoi_irq+0xd0/0x190 [ 3.905117] generic_handle_irq+0x30/0x48 [ 3.909111] __handle_domain_irq+0x64/0xc0 [ 3.913192] gic_handle_irq+0x78/0xa0 [ 3.916846] el1_irq+0xc4/0x180 [ 3.919982] cpuidle_enter_state+0x134/0x2f8 [ 3.924243] cpuidle_enter+0x38/0x50 [ 3.927810] call_cpuidle+0x1c/0x40 [ 3.931290] do_idle+0x20c/0x270 [ 3.934502] cpu_startup_entry+0x28/0x58 [ 3.938410] rest_init+0xbc/0xcc [ 3.941631] arch_call_rest_init+0x10/0x1c [ 3.945718] start_kernel+0x51c/0x558
--- drivers/dma/xilinx/xilinx_dpdma.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
drivers/dma/xilinx/xilinx_dpdma.c +23 -1
@@ -1459,7 +1459,7 @@ static void xilinx_dpdma_enable_irq(struct xilinx_dpdma_device *xdev)*/ static void xilinx_dpdma_disable_irq (struct xilinx_dpdma_device *xdev) { -dpdma_write (xdev->reg,XILINX_DPDMA_IDS ,XILINX_DPDMA_INTR_ERR_ALL ); +dpdma_write (xdev->reg,XILINX_DPDMA_IDS ,XILINX_DPDMA_INTR_ALL );dpdma_write (xdev->reg,XILINX_DPDMA_EIDS ,XILINX_DPDMA_EINTR_ALL ); }
@@ -1596,6 +1596,26 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,return dma_get_slave_channel (&xdev->chan[chan_id]->vchan.chan); } +static void dpdma_hw_init (struct xilinx_dpdma_device *xdev) +{ +unsigned int i; +void __iomem *reg; + +/* Disable all interrupts */ +xilinx_dpdma_disable_irq (xdev); + +/* Stop all channels */ +for (i =0 ; i <ARRAY_SIZE (xdev->chan); i++) { + reg = xdev->reg +XILINX_DPDMA_CH_BASE + +XILINX_DPDMA_CH_OFFSET * i; +dpdma_clr (reg,XILINX_DPDMA_CH_CNTL ,XILINX_DPDMA_CH_CNTL_ENABLE ); + } + +/* Clear the interrupt status registers */ +dpdma_write (xdev->reg,XILINX_DPDMA_ISR ,XILINX_DPDMA_INTR_ALL ); +dpdma_write (xdev->reg,XILINX_DPDMA_EISR ,XILINX_DPDMA_EINTR_ALL ); +} +static int xilinx_dpdma_probe (struct platform_device *pdev) {struct xilinx_dpdma_device *xdev;
@@ -1622,6 +1642,8 @@ static int xilinx_dpdma_probe(struct platform_device *pdev)if (IS_ERR (xdev->reg))return PTR_ERR (xdev->reg); +dpdma_hw_init (xdev); + xdev->irq =platform_get_irq (pdev,0 );if (xdev->irq <0 ) {dev_err (xdev->dev,"failed to get platform irq\n" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 5/178 dmaengine: ALTERA_MSGDMA depends on HAS_IOMEM
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 253697b93c2a1c237d34d3ae326e394aeb0ca7b3 ]
When CONFIG_HAS_IOMEM is not set/enabled, certain iomap() family functions [including ioremap(), devm_ioremap(), etc.] are not available.
Drivers that use these functions should depend on HAS_IOMEM so that they do not cause build errors.
Repairs this build error:
s390-linux-ld: drivers/dma/altera-msgdma.o: in function `request_and_map':
altera-msgdma.c:(.text+0x14b0): undefined reference to `devm_ioremap'
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: [email protected]
--- drivers/dma/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/dma/Kconfig +1 -0
@@ -59,6 +59,7 @@ config DMA_OF #devices config ALTERA_MSGDMA tristate "Altera / Intel mSGDMA Engine" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for Altera / Intel mSGDMA controller.
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 6/178 dmaengine: QCOM_HIDMA_MGMT depends on HAS_IOMEM
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 0cfbb589d67f16fa55b26ae02b69c31b52e344b1 ]
When CONFIG_HAS_IOMEM is not set/enabled, certain iomap() family functions [including ioremap(), devm_ioremap(), etc.] are not available.
Drivers that use these functions should depend on HAS_IOMEM so that they do not cause build errors.
Rectifies these build errors:
s390-linux-ld: drivers/dma/qcom/hidma_mgmt.o: in function `hidma_mgmt_probe':
hidma_mgmt.c:(.text+0x780): undefined reference to `devm_ioremap_resource'
s390-linux-ld: drivers/dma/qcom/hidma_mgmt.o: in function `hidma_mgmt_init':
hidma_mgmt.c:(.init.text+0x126): undefined reference to `of_address_to_resource'
s390-linux-ld: hidma_mgmt.c:(.init.text+0x16e): undefined reference to `of_address_to_resource'
--- drivers/dma/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/dma/qcom/Kconfig +1 -0
@@ -33,6 +33,7 @@ config QCOM_GPI_DMA config QCOM_HIDMA_MGMT tristate "Qualcomm Technologies HIDMA Management support" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for the Qualcomm Technologies HIDMA Management.
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 7/178 dmaengine: SF_PDMA depends on HAS_IOMEM
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 8e2e4f3c58528c6040b5762b666734f8cceba568 ]
When CONFIG_HAS_IOMEM is not set/enabled, certain iomap() family functions [including ioremap(), devm_ioremap(), etc.] are not available.
Drivers that use these functions should depend on HAS_IOMEM so that they do not cause build errors.
Mends this build error:
s390-linux-ld: drivers/dma/sf-pdma/sf-pdma.o: in function `sf_pdma_probe':
sf-pdma.c:(.text+0x1668): undefined reference to `devm_ioremap_resource'
--- drivers/dma/sf-pdma/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/dma/sf-pdma/Kconfig +1 -0
@@ -1,5 +1,6 @@ config SF_PDMA tristate "Sifive PDMA controller driver" + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 8/178 dmaengine: stedma40: add missing iounmap() on error in d40_probe()
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
[ Upstream commit fffdaba402cea79b8d219355487d342ec23f91c6 ]
Add the missing iounmap() before return from d40_probe() in the error handling case.
--- drivers/dma/ste_dma40.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/dma/ste_dma40.c +3 -0
@@ -3675,6 +3675,9 @@ static int __init d40_probe(struct platform_device *pdev)kfree (base->lcla_pool.base_unaligned); +if (base->lcpa_base) +iounmap (base->lcpa_base); +if (base->phy_lcpa)release_mem_region (base->phy_lcpa, base->lcpa_size);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 9/178 afs: Fix an IS_ERR() vs NULL check
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit a33d62662d275cee22888fa7760fe09d5b9cd1f9 ]
The proc_symlink() function returns NULL on error, it doesn't return error pointers.
--- fs/afs/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/afs/main.c +2 -2
@@ -203,8 +203,8 @@ static int __init afs_init(void) goto error_fs; afs_proc_symlink =proc_symlink ("fs/afs" ,NULL ,"../self/net/afs" ); -if (IS_ERR (afs_proc_symlink)) { - ret =PTR_ERR (afs_proc_symlink); +if (!afs_proc_symlink) { + ret = -ENOMEM ; goto error_proc; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 10/178 mm/memory-failure: make sure wait for page writeback in memory_failure
In reply to Greg Kroah-HartmanFrom: yangerkun <[email protected]>
[ Upstream commit e8675d291ac007e1c636870db880f837a9ea112a ]
Our syzkaller trigger the "BUG_ON(!list_empty(&inode->i_wb_list))" in clear_inode:
kernel BUG at fs/inode.c:519!
Internal error: Oops - BUG: 0 [#1] SMP
Modules linked in:
Process syz-executor.0 (pid: 249, stack limit = 0x00000000a12409d7)
CPU: 1 PID: 249 Comm: syz-executor.0 Not tainted 4.19.95
Hardware name: linux,dummy-virt (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO)
pc : clear_inode+0x280/0x2a8
lr : clear_inode+0x280/0x2a8
Call trace:
clear_inode+0x280/0x2a8
ext4_clear_inode+0x38/0xe8
ext4_free_inode+0x130/0xc68
ext4_evict_inode+0xb20/0xcb8
evict+0x1a8/0x3c0
iput+0x344/0x460
do_unlinkat+0x260/0x410
__arm64_sys_unlinkat+0x6c/0xc0
el0_svc_common+0xdc/0x3b0
el0_svc_handler+0xf8/0x160
el0_svc+0x10/0x218
Kernel panic - not syncing: Fatal exceptionA crash dump of this problem show that someone called __munlock_pagevec to clear page LRU without lock_page: do_mmap -> mmap_region -> do_munmap -> munlock_vma_pages_range -> __munlock_pagevec.
As a result memory_failure will call identify_page_state without wait_on_page_writeback. And after truncate_error_page clear the mapping of this page. end_page_writeback won't call sb_clear_inode_writeback to clear inode->i_wb_list. That will trigger BUG_ON in clear_inode!
Fix it by checking PageWriteback too to help determine should we skip wait_on_page_writeback.
--- mm/memory-failure.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
mm/memory-failure.c +6 -1
@@ -1527,7 +1527,12 @@ try_again:return 0 ; } -if (!PageTransTail (p) && !PageLRU (p)) +/* +* __munlock_pagevec may clear a writeback page's LRU flag without +* page_lock. We need wait writeback completion for this page or it +* may trigger vfs BUG while evict inode. +*/ +if (!PageTransTail (p) && !PageLRU (p) && !PageWriteback (p)) goto identify_page_state;/*
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 11/178 kvm: LAPIC: Restore guard to prevent illegal APIC register access
In reply to Greg Kroah-HartmanFrom: Jim Mattson <[email protected]>
[ Upstream commit 218bf772bddd221489c38dde6ef8e917131161f6 ]
Per the SDM, "any access that touches bytes 4 through 15 of an APIC register may cause undefined behavior and must not be executed." Worse, such an access in kvm_lapic_reg_read can result in a leak of kernel stack contents. Prior to commit 01402cf81051 ("kvm: LAPIC:
write down valid APIC registers"), such an access was explicitly disallowed. Restore the guard that was removed in that commit.
Message-Id: <[email protected]>
--- arch/x86/kvm/lapic.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kvm/lapic.c +3 -0
@@ -1410,6 +1410,9 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len,if (!apic_x2apic_mode (apic)) valid_reg_mask |=APIC_REG_MASK (APIC_ARBPRI ); +if (alignment + len >4 ) +return 1 ; +if (offset >0x3f0 || !(valid_reg_mask &APIC_REG_MASK (offset)))return 1 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 12/178 fanotify: fix copy_event_to_user() fid error clean up
In reply to Greg Kroah-HartmanFrom: Matthew Bobrowski <[email protected]>
[ Upstream commit f644bc449b37cc32d3ce7b36a88073873aa21bd5 ]
Ensure that clean up is performed on the allocated file descriptor and struct file object in the event that an error is encountered while copying fid info objects. Currently, we return directly to the caller when an error is experienced in the fid info copying helper, which isn't ideal given that the listener process could be left with a dangling file descriptor in their fdtable.
--- fs/notify/fanotify/fanotify_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/notify/fanotify/fanotify_user.c +2 -2
@@ -378,7 +378,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, info_type,fanotify_info_name (info), info->name_len, buf, count);if (ret <0 ) -return ret; + goto out_close_fd; buf += ret; count -= ret;
@@ -426,7 +426,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,fanotify_event_object_fh (event), info_type, dot, dot_len, buf, count);if (ret <0 ) -return ret; + goto out_close_fd; buf += ret; count -= ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 13/178 batman-adv: Avoid WARN_ON timing related checks
In reply to Greg Kroah-HartmanFrom: Sven Eckelmann <[email protected]>
[ Upstream commit 9f460ae31c4435fd022c443a6029352217a16ac1 ]
The soft/batadv interface for a queued OGM can be changed during the time the OGM was queued for transmission and when the OGM is actually transmitted by the worker.
But WARN_ON must be used to denote kernel bugs and not to print simple warnings. A warning can simply be printed using pr_warn.
--- net/batman-adv/bat_iv_ogm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/batman-adv/bat_iv_ogm.c +3 -1
@@ -409,8 +409,10 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)if (WARN_ON (!forw_packet->if_outgoing))return ; -if (WARN_ON (forw_packet->if_outgoing->soft_iface != soft_iface)) +if (forw_packet->if_outgoing->soft_iface != soft_iface) { +pr_warn ("%s: soft interface switch for queued OGM\n" , __func__);return ; + }if (forw_packet->if_incoming->if_status !=BATADV_IF_ACTIVE )return ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 14/178 staging: rtl8723bs: fix monitor netdev register/unregister
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit b90f51e8e1f5014c01c82a7bf4c611643d0a8bcb ]
Due to the locking changes and callbacks happening inside cfg80211, we need to use cfg80211 versions of the register and unregister functions if called within cfg80211 methods, otherwise deadlocks occur.
--- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +2 -2
@@ -2579,7 +2579,7 @@ static int rtw_cfg80211_add_monitor_if(struct adapter *padapter, char *name, str mon_wdev->iftype =NL80211_IFTYPE_MONITOR ; mon_ndev->ieee80211_ptr = mon_wdev; - ret =register_netdevice (mon_ndev); + ret =cfg80211_register_netdevice (mon_ndev);if (ret) { goto out; }
@@ -2661,7 +2661,7 @@ static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, adapter =rtw_netdev_priv (ndev); pwdev_priv =adapter_wdev_data (adapter); -unregister_netdevice (ndev); +cfg80211_unregister_netdevice (ndev);if (ndev == pwdev_priv->pmon_ndev) { pwdev_priv->pmon_ndev =NULL ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 15/178 mac80211: fix skb length check in ieee80211_scan_rx()
In reply to Greg Kroah-HartmanFrom: Du Cheng <[email protected]>
[ Upstream commit e298aa358f0ca658406d524b6639fe389cb6e11e ]
Replace hard-coded compile-time constants for header length check with dynamic determination based on the frame type. Otherwise, we hit a validation WARN_ON in cfg80211 later.
--- net/mac80211/scan.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
net/mac80211/scan.c +16 -5
@@ -251,13 +251,24 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)struct ieee80211_mgmt *mgmt = (void *)skb->data;struct ieee80211_bss *bss;struct ieee80211_channel *channel; +size_t min_hdr_len = offsetof(struct ieee80211_mgmt , + u.probe_resp.variable); + +if (!ieee80211_is_probe_resp (mgmt->frame_control) && + !ieee80211_is_beacon (mgmt->frame_control) && + !ieee80211_is_s1g_beacon (mgmt->frame_control)) +return ;if (ieee80211_is_s1g_beacon (mgmt->frame_control)) { -if (skb->len <15 ) -return ; - }else if (skb->len <24 || - (!ieee80211_is_probe_resp (mgmt->frame_control) && - !ieee80211_is_beacon (mgmt->frame_control))) +if (ieee80211_is_s1g_short_beacon (mgmt->frame_control)) + min_hdr_len = offsetof(struct ieee80211_ext , + u.s1g_short_beacon.variable); +else + min_hdr_len = offsetof(struct ieee80211_ext , + u.s1g_beacon); + } + +if (skb->len < min_hdr_len)return ; sdata1 =rcu_dereference (local->scan_sdata);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 16/178 mlxsw: reg: Spectrum-3: Enforce lowest max-shaper burst size of 11
In reply to Greg Kroah-HartmanFrom: Petr Machata <[email protected]>
[ Upstream commit 306b9228c097b4101c150ccd262372ded8348644 ]
A max-shaper is the HW component responsible for delaying egress traffic above a configured transmission rate. Burst size is the amount of traffic that is allowed to pass without accounting. The burst size value needs to be such that it can be expressed as 2^BS * 512 bits, where BS lies in a certain ASIC-dependent range. mlxsw enforces that this holds before attempting to configure the shaper.
The assumption for Spectrum-3 was that the lower limit of BS would be 5, like for Spectrum-1. But as of now, the limit is still 11. Therefore fix the driver accordingly, so that incorrect values are rejected early with a proper message.
--- drivers/net/ethernet/mellanox/mlxsw/reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/reg.h +1 -1
@@ -3863,7 +3863,7 @@ MLXSW_ITEM32(reg, qeec, max_shaper_bs, 0x1C, 0, 6);#define MLXSW_REG_QEEC_HIGHEST_SHAPER_BS 25#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1 5#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2 11 -#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3 5 +#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3 11 static inline void mlxsw_reg_qeec_pack(char *payload, u8 local_port, enum mlxsw_reg_qeec_hr hr, u8 index,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 17/178 mlxsw: core: Set thermal zone polling delay argument to real value at init
In reply to Greg Kroah-HartmanFrom: Mykola Kostenok <[email protected]>
[ Upstream commit 2fd8d84ce3095e8a7b5fe96532c91b1b9e07339c ]
Thermal polling delay argument for modules and gearboxes thermal zones used to be initialized with zero value, while actual delay was used to be set by mlxsw_thermal_set_mode() by thermal operation callback set_mode(). After operations set_mode()/get_mode() have been removed by cited commits, modules and gearboxes thermal zones always have polling time set to zero and do not perform temperature monitoring.
Set non-zero "polling_delay" in thermal_zone_device_register() routine, thus, the relevant thermal zones will perform thermal monitoring.
--- drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +4 -2
@@ -708,7 +708,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)MLXSW_THERMAL_TRIP_MASK , module_tz, &mlxsw_thermal_module_ops, - NULL, 0, 0); +NULL ,0 , + module_tz->parent->polling_delay);if (IS_ERR (module_tz->tzdev)) { err =PTR_ERR (module_tz->tzdev);return err;
@@ -830,7 +831,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)MLXSW_THERMAL_TRIP_MASK , gearbox_tz, &mlxsw_thermal_gearbox_ops, - NULL, 0, 0); +NULL ,0 , + gearbox_tz->parent->polling_delay);if (IS_ERR (gearbox_tz->tzdev))return PTR_ERR (gearbox_tz->tzdev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 18/178 libbpf: Fixes incorrect rx_ring_setup_done
In reply to Greg Kroah-HartmanFrom: Kev Jackson <[email protected]>
[ Upstream commit 11fc79fc9f2e395aa39fa5baccae62767c5d8280 ]
When calling xsk_socket__create_shared(), the logic at line 1097 marks a boolean flag true within the xsk_umem structure to track setup progress in order to support multiple calls to the function. However, instead of marking umem->tx_ring_setup_done, the code incorrectly sets umem->rx_ring_setup_done. This leads to improper behaviour when creating and destroying xsk and umem structures.
Multiple calls to this function is documented as supported.
--- tools/lib/bpf/xsk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/lib/bpf/xsk.c +1 -1
@@ -928,7 +928,7 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr, goto out_put_ctx; }if (xsk->fd == umem->fd) - umem->rx_ring_setup_done = true; + umem->tx_ring_setup_done = true; } err =xsk_get_mmap_offsets (xsk->fd, &off);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 19/178 net: ipv4: fix memory leak in netlbl_cipsov4_add_std
In reply to Greg Kroah-HartmanFrom: Nanyong Sun <[email protected]>
[ Upstream commit d612c3f3fae221e7ea736d196581c2217304bbbc ]
Reported by syzkaller:
BUG: memory leak
unreferenced object 0xffff888105df7000 (size 64):
comm "syz-executor842", pid 360, jiffies 4294824824 (age 22.546s) hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace:
[<00000000e67ed558>] kmalloc include/linux/slab.h:590 [inline] [<00000000e67ed558>] kzalloc include/linux/slab.h:720 [inline] [<00000000e67ed558>] netlbl_cipsov4_add_std net/netlabel/netlabel_cipso_v4.c:145 [inline] [<00000000e67ed558>] netlbl_cipsov4_add+0x390/0x2340 net/netlabel/netlabel_cipso_v4.c:416 [<0000000006040154>] genl_family_rcv_msg_doit.isra.0+0x20e/0x320 net/netlink/genetlink.c:739 [<00000000204d7a1c>] genl_family_rcv_msg net/netlink/genetlink.c:783 [inline] [<00000000204d7a1c>] genl_rcv_msg+0x2bf/0x4f0 net/netlink/genetlink.c:800 [<00000000c0d6a995>] netlink_rcv_skb+0x134/0x3d0 net/netlink/af_netlink.c:2504 [<00000000d78b9d2c>] genl_rcv+0x24/0x40 net/netlink/genetlink.c:811 [<000000009733081b>] netlink_unicast_kernel net/netlink/af_netlink.c:1314 [inline] [<000000009733081b>] netlink_unicast+0x4a0/0x6a0 net/netlink/af_netlink.c:1340 [<00000000d5fd43b8>] netlink_sendmsg+0x789/0xc70 net/netlink/af_netlink.c:1929 [<000000000a2d1e40>] sock_sendmsg_nosec net/socket.c:654 [inline] [<000000000a2d1e40>] sock_sendmsg+0x139/0x170 net/socket.c:674 [<00000000321d1969>] ____sys_sendmsg+0x658/0x7d0 net/socket.c:2350 [<00000000964e16bc>] ___sys_sendmsg+0xf8/0x170 net/socket.c:2404 [<000000001615e288>] __sys_sendmsg+0xd3/0x190 net/socket.c:2433 [<000000004ee8b6a5>] do_syscall_64+0x37/0x90 arch/x86/entry/common.c:47 [<00000000171c7cee>] entry_SYSCALL_64_after_hwframe+0x44/0xae
The memory of doi_def->map.std pointing is allocated in netlbl_cipsov4_add_std, but no place has freed it. It should be freed in cipso_v4_doi_free which frees the cipso DOI resource.
--- net/ipv4/cipso_ipv4.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/cipso_ipv4.c +1 -0
@@ -472,6 +472,7 @@ void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)kfree (doi_def->map.std->lvl.local);kfree (doi_def->map.std->cat.cipso);kfree (doi_def->map.std->cat.local); +kfree (doi_def->map.std);break ; }kfree (doi_def);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 20/178 vrf: fix maximum MTU
In reply to Greg Kroah-HartmanFrom: Nicolas Dichtel <[email protected]>
[ Upstream commit 9bb392f62447d73cc7dd7562413a2cd9104c82f8 ]
My initial goal was to fix the default MTU, which is set to 65536, ie above the maximum defined in the driver: 65535 (ETH_MAX_MTU).
In fact, it's seems more consistent, wrt min_mtu, to set the max_mtu to IP6_MAX_MTU (65535 + sizeof(struct ipv6hdr)) and use it by default.
Let's also, for consistency, set the mtu in vrf_setup(). This function calls ether_setup(), which set the mtu to 1500. Thus, the whole mtu config is done in the same function.
Before the patch:
$ ip link add blue type vrf table 1234
$ ip link list blue
9: blue: <NOARP,MASTER> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether fa:f5:27:70:24:2a brd ff:ff:ff:ff:ff:ff
$ ip link set dev blue mtu 65535
$ ip link set dev blue mtu 65536
Error: mtu greater than device maximum.--- drivers/net/vrf.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/vrf.c +2 -4
@@ -1183,9 +1183,6 @@ static int vrf_dev_init(struct net_device *dev) dev->flags =IFF_MASTER |IFF_NOARP ; -/* MTU is irrelevant for VRF device; set to 64k similar to lo */ - dev->mtu =64 *1024 ; -/* similarly, oper state is irrelevant; set to up to avoid confusion */ dev->operstate =IF_OPER_UP ;netdev_lockdep_set_classes (dev);
@@ -1685,7 +1682,8 @@ static void vrf_setup(struct net_device *dev)* which breaks networking. */ dev->min_mtu =IPV6_MIN_MTU ; - dev->max_mtu =ETH_MAX_MTU ; + dev->max_mtu =IP6_MAX_MTU ; + dev->mtu = dev->max_mtu; } static int vrf_validate(struct nlattr *tb[], struct nlattr *data[],
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 21/178 net: rds: fix memory leak in rds_recvmsg
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit 49bfcbfd989a8f1f23e705759a6bb099de2cff9f ]
Syzbot reported memory leak in rds. The problem was in unputted refcount in case of error.
int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
int msg_flags)
{
...
if (!rds_next_incoming(rs, &inc)) {
...
}After this "if" inc refcount incremented and
if (rds_cmsg_recv(inc, msg, rs)) {
ret = -EFAULT;
goto out;
}
...
out:
return ret;
}in case of rds_cmsg_recv() fail the refcount won't be decremented. And it's easy to see from ftrace log, that rds_inc_addref() don't have rds_inc_put() pair in rds_recvmsg() after rds_cmsg_recv()
1) | rds_recvmsg() {
1) 3.721 us | rds_inc_addref();
1) 3.853 us | rds_message_inc_copy_to_user();
1) + 10.395 us | rds_cmsg_recv();
1) + 34.260 us | }--- net/rds/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rds/recv.c +1 -1
@@ -714,7 +714,7 @@ int rds_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,if (rds_cmsg_recv (inc, msg, rs)) { ret = -EFAULT ; - goto out; +break ; }rds_recvmsg_zcookie (rs, msg);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 22/178 net: dsa: felix: re-enable TX flow control in ocelot_port_flush()
In reply to Greg Kroah-HartmanFrom: Vladimir Oltean <[email protected]>
[ Upstream commit 1650bdb1c516c248fb06f6d076559ff6437a5853 ]
Because flow control is set up statically in ocelot_init_port(), and not in phylink_mac_link_up(), what happens is that after the blamed commit, the flow control remains disabled after the port flushing procedure.
--- drivers/net/ethernet/mscc/ocelot.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/mscc/ocelot.c +5 -0
@@ -378,6 +378,7 @@ static u32 ocelot_read_eq_avail(struct ocelot *ocelot, int port)int ocelot_port_flush (struct ocelot *ocelot,int port) { +unsigned int pause_ena;int err, val;/* Disable dequeuing from the egress queues */
@@ -386,6 +387,7 @@ int ocelot_port_flush(struct ocelot *ocelot, int port) QSYS_PORT_MODE, port);/* Disable flow control */ +ocelot_fields_read (ocelot, port,SYS_PAUSE_CFG_PAUSE_ENA , &pause_ena);ocelot_fields_write (ocelot, port,SYS_PAUSE_CFG_PAUSE_ENA ,0 );/* Disable priority flow control */
@@ -421,6 +423,9 @@ int ocelot_port_flush(struct ocelot *ocelot, int port)/* Clear flushing again. */ ocelot_rmw_gix (ocelot,0 ,REW_PORT_CFG_FLUSH_ENA ,REW_PORT_CFG , port); +/* Re-enable flow control */ +ocelot_fields_write (ocelot, port,SYS_PAUSE_CFG_PAUSE_ENA , pause_ena); +return err; }EXPORT_SYMBOL (ocelot_port_flush);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 23/178 net: ena: fix DMA mapping function issues in XDP
In reply to Greg Kroah-HartmanFrom: Shay Agroskin <[email protected]>
[ Upstream commit 504fd6a5390c30b1b7670768e314dd5d473da06a ]
This patch fixes several bugs found when (DMA/LLQ) mapping a packet for transmission. The mapping procedure makes the transmitted packet accessible by the device.
When using LLQ, this requires copying the packet's header to push header (which would be passed to LLQ) and creating DMA mapping for the payload (if the packet doesn't fit the maximum push length).
When not using LLQ, we map the whole packet with DMA.
The following bugs are fixed in the code:
1. Add support for non-LLQ machines:
The ena_xdp_tx_map_frame() function assumed that LLQ is supported, and never mapped the whole packet using DMA. On some instances, which don't support LLQ, this causes loss of traffic.
2. Wrong DMA buffer length passed to device:
When using LLQ, the first 'tx_max_header_size' bytes of the packet would be copied to push header. The rest of the packet would be copied to a DMA'd buffer.
3. Freeing the XDP buffer twice in case of a mapping error:
In case a buffer DMA mapping fails, the function uses xdp_return_frame_rx_napi() to free the RX buffer and returns from the function with an error. XDP frames that fail to xmit get freed by the kernel and so there is no need for this call.
--- drivers/net/ethernet/amazon/ena/ena_netdev.c | 54 ++++++++++---------- 1 file changed, 28 insertions(+), 26 deletions(-)
drivers/net/ethernet/amazon/ena/ena_netdev.c +28 -26
@@ -236,36 +236,48 @@ static int ena_xdp_io_poll(struct napi_struct *napi, int budget)static int ena_xdp_tx_map_frame (struct ena_ring *xdp_ring,struct ena_tx_buffer *tx_info,struct xdp_frame *xdpf, -void **push_hdr, -u32 *push_len) +struct ena_com_tx_ctx *ena_tx_ctx) {struct ena_adapter *adapter = xdp_ring->adapter;struct ena_com_buf *ena_buf; -dma_addr_t dma =0 ; +int push_len =0 ; +dma_addr_t dma; +void *data;u32 size; tx_info->xdpf = xdpf; + data = tx_info->xdpf->data; size = tx_info->xdpf->len; - ena_buf = tx_info->bufs; -/* llq push buffer */ - *push_len =min_t (u32, size, xdp_ring->tx_max_header_size); - *push_hdr = tx_info->xdpf->data; +if (xdp_ring->tx_mem_queue_type ==ENA_ADMIN_PLACEMENT_POLICY_DEV ) { +/* Designate part of the packet for LLQ */ + push_len =min_t (u32, size, xdp_ring->tx_max_header_size); + + ena_tx_ctx->push_header = data; + + size -= push_len; + data += push_len; + } + + ena_tx_ctx->header_len = push_len; -if (size - *push_len >0 ) { +if (size >0 ) { dma =dma_map_single (xdp_ring->dev, - *push_hdr + *push_len, - size - *push_len, + data, + size,DMA_TO_DEVICE );if (unlikely (dma_mapping_error (xdp_ring->dev, dma))) goto error_report_dma_error; - tx_info->map_linear_data =1 ; - tx_info->num_of_bufs =1 ; - } + tx_info->map_linear_data =0 ; - ena_buf->paddr = dma; - ena_buf->len = size; + ena_buf = tx_info->bufs; + ena_buf->paddr = dma; + ena_buf->len = size; + + ena_tx_ctx->ena_bufs = ena_buf; + ena_tx_ctx->num_bufs = tx_info->num_of_bufs =1 ; + }return 0 ;
@@ -274,10 +286,6 @@ error_report_dma_error: &xdp_ring->syncp);netif_warn (adapter, tx_queued, adapter->netdev,"Failed to map xdp buff\n" ); -xdp_return_frame_rx_napi (tx_info->xdpf); - tx_info->xdpf =NULL ; - tx_info->num_of_bufs =0 ; -return -EINVAL ; }
@@ -289,8 +297,6 @@ static int ena_xdp_xmit_frame(struct ena_ring *xdp_ring,struct ena_com_tx_ctx ena_tx_ctx = {};struct ena_tx_buffer *tx_info;u16 next_to_use, req_id; -void *push_hdr; -u32 push_len;int rc; next_to_use = xdp_ring->next_to_use;
@@ -298,15 +304,11 @@ static int ena_xdp_xmit_frame(struct ena_ring *xdp_ring, tx_info = &xdp_ring->tx_buffer_info[req_id]; tx_info->num_of_bufs =0 ; - rc =ena_xdp_tx_map_frame (xdp_ring, tx_info, xdpf, &push_hdr, &push_len); + rc =ena_xdp_tx_map_frame (xdp_ring, tx_info, xdpf, &ena_tx_ctx);if (unlikely (rc)) goto error_drop_packet; - ena_tx_ctx.ena_bufs = tx_info->bufs; - ena_tx_ctx.push_header = push_hdr; - ena_tx_ctx.num_bufs = tx_info->num_of_bufs; ena_tx_ctx.req_id = req_id; - ena_tx_ctx.header_len = push_len; rc = ena_xmit_common(dev, xdp_ring,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 24/178 net: lantiq: disable interrupt before sheduling NAPI
In reply to Greg Kroah-HartmanFrom: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit f2386cf7c5f4ff5d7b584f5d92014edd7df6c676 ]
This patch fixes TX hangs with threaded NAPI enabled. The scheduled NAPI seems to be executed in parallel with the interrupt on second thread. Sometimes it happens that ltq_dma_disable_irq() is executed after xrx200_tx_housekeeping(). The symptom is that TX interrupts are disabled in the DMA controller. As a result, the TX hangs after a few seconds of the iperf test. Scheduling NAPI after disabling interrupts fixes this issue.
Tested on Lantiq xRX200 (BT Home Hub 5A).
--- drivers/net/ethernet/lantiq_xrx200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/lantiq_xrx200.c +1 -1
@@ -352,8 +352,8 @@ static irqreturn_t xrx200_dma_irq(int irq, void *ptr)struct xrx200_chan *ch = ptr;if (napi_schedule_prep (&ch->napi)) { -__napi_schedule (&ch->napi);ltq_dma_disable_irq (&ch->dma); +__napi_schedule (&ch->napi); }ltq_dma_ack_irq (&ch->dma);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 25/178 netfilter: nf_tables: initialize set before expression setup
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ Upstream commit ad9f151e560b016b6ad3280b48e42fa11e1a5440 ]
nft_set_elem_expr_alloc() needs an initialized set if expression sets on the NFT_EXPR_GC flag. Move set fields initialization before expression setup.
[4512935.019450] ================================================================== [4512935.019456] BUG: KASAN: null-ptr-deref in nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables] [4512935.019487] Read of size 8 at addr 0000000000000070 by task nft/23532 [4512935.019494] CPU: 1 PID: 23532 Comm: nft Not tainted 5.12.0-rc4+ #48 [...] [4512935.019502] Call Trace: [4512935.019505] dump_stack+0x89/0xb4 [4512935.019512] ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables] [4512935.019536] ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables] [4512935.019560] kasan_report.cold.12+0x5f/0xd8 [4512935.019566] ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables] [4512935.019590] nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables] [4512935.019615] nf_tables_newset+0xc7f/0x1460 [nf_tables]
--- net/netfilter/nf_tables_api.c | 83 ++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 41 deletions(-)
net/netfilter/nf_tables_api.c +42 -41
@@ -4317,13 +4317,44 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, err =nf_tables_set_alloc_name (&ctx, set, name);kfree (name);if (err <0 ) - goto err_set_alloc_name; + goto err_set_name; + + udata =NULL ; +if (udlen) { + udata = set->data + size; +nla_memcpy (udata, nla[NFTA_SET_USERDATA ], udlen); + } + +INIT_LIST_HEAD (&set->bindings); + set->table = table; +write_pnet (&set->net, net); + set->ops = ops; + set->ktype = ktype; + set->klen = desc.klen; + set->dtype = dtype; + set->objtype = objtype; + set->dlen = desc.dlen; + set->flags = flags; + set->size = desc.size; + set->policy = policy; + set->udlen = udlen; + set->udata = udata; + set->timeout = timeout; + set->gc_int = gc_int; + + set->field_count = desc.field_count; +for (i =0 ; i < desc.field_count; i++) + set->field_len[i] = desc.field_len[i]; + + err = ops->init (set, &desc, nla); +if (err <0 ) + goto err_set_init;if (nla[NFTA_SET_EXPR ]) { expr =nft_set_elem_expr_alloc (&ctx, set, nla[NFTA_SET_EXPR ]);if (IS_ERR (expr)) { err =PTR_ERR (expr); - goto err_set_alloc_name; + goto err_set_expr_alloc; } set->exprs[0 ] = expr; set->num_exprs++;
@@ -4334,74 +4365,44 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,if (!(flags &NFT_SET_EXPR )) { err = -EINVAL ; - goto err_set_alloc_name; + goto err_set_expr_alloc; } i =0 ;nla_for_each_nested (tmp, nla[NFTA_SET_EXPRESSIONS ], left) {if (i ==NFT_SET_EXPR_MAX ) { err = -E2BIG ; - goto err_set_init; + goto err_set_expr_alloc; }if (nla_type (tmp) !=NFTA_LIST_ELEM ) { err = -EINVAL ; - goto err_set_init; + goto err_set_expr_alloc; } expr =nft_set_elem_expr_alloc (&ctx, set, tmp);if (IS_ERR (expr)) { err =PTR_ERR (expr); - goto err_set_init; + goto err_set_expr_alloc; } set->exprs[i++] = expr; set->num_exprs++; } } - udata =NULL ; -if (udlen) { - udata = set->data + size; -nla_memcpy (udata, nla[NFTA_SET_USERDATA ], udlen); - } - -INIT_LIST_HEAD (&set->bindings); - set->table = table; -write_pnet (&set->net, net); - set->ops = ops; - set->ktype = ktype; - set->klen = desc.klen; - set->dtype = dtype; - set->objtype = objtype; - set->dlen = desc.dlen; - set->flags = flags; - set->size = desc.size; - set->policy = policy; - set->udlen = udlen; - set->udata = udata; - set->timeout = timeout; - set->gc_int = gc_int; set->handle =nf_tables_alloc_handle (table); - set->field_count = desc.field_count; -for (i =0 ; i < desc.field_count; i++) - set->field_len[i] = desc.field_len[i]; - - err = ops->init (set, &desc, nla); -if (err <0 ) - goto err_set_init; - err =nft_trans_set_add (&ctx,NFT_MSG_NEWSET , set);if (err <0 ) - goto err_set_trans; + goto err_set_expr_alloc;list_add_tail_rcu (&set->list, &table->sets); table->use++;return 0 ; -err_set_trans: - ops->destroy (set); -err_set_init: +err_set_expr_alloc:for (i =0 ; i < set->num_exprs; i++)nft_expr_destroy (&ctx, set->exprs[i]); -err_set_alloc_name: + + ops->destroy (set); +err_set_init:kfree (set->name); err_set_name:kvfree (set);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 26/178 netfilter: nft_fib_ipv6: skip ipv6 packets from any to link-local
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit 12f36e9bf678a81d030ca1b693dcda62b55af7c5 ]
The ip6tables rpfilter match has an extra check to skip packets with "::" source address.
Extend this to ipv6 fib expression. Else ipv6 duplicate address detection packets will fail rpf route check -- lookup returns -ENETUNREACH.
While at it, extend the prerouting check to also cover the ingress hook.
--- net/ipv6/netfilter/nft_fib_ipv6.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
net/ipv6/netfilter/nft_fib_ipv6.c +18 -4
@@ -135,6 +135,17 @@ void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs, }EXPORT_SYMBOL_GPL (nft_fib6_eval_type); +static bool nft_fib_v6_skip_icmpv6 (const struct sk_buff *skb,u8 next,const struct ipv6hdr *iph) +{ +if (likely (next !=IPPROTO_ICMPV6 )) +return false; + +if (ipv6_addr_type (&iph->saddr) !=IPV6_ADDR_ANY ) +return false; + +return ipv6_addr_type (&iph->daddr) &IPV6_ADDR_LINKLOCAL ; +} +void nft_fib6_eval (const struct nft_expr *expr,struct nft_regs *regs,const struct nft_pktinfo *pkt) {
@@ -163,10 +174,13 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs, lookup_flags =nft_fib6_flowi_init (&fl6, priv, pkt, oif, iph); -if (nft_hook (pkt) ==NF_INET_PRE_ROUTING && -nft_fib_is_loopback (pkt->skb,nft_in (pkt))) { -nft_fib_store_result (dest, priv,nft_in (pkt)); -return ; +if (nft_hook (pkt) ==NF_INET_PRE_ROUTING || +nft_hook (pkt) ==NF_INET_INGRESS ) { +if (nft_fib_is_loopback (pkt->skb,nft_in (pkt)) || +nft_fib_v6_skip_icmpv6 (pkt->skb, pkt->tprot, iph)) { +nft_fib_store_result (dest, priv,nft_in (pkt)); +return ; + } } *dest =0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 27/178 ice: add ndo_bpf callback for safe mode netdev ops
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
[ Upstream commit ebc5399ea1dfcddac31974091086a3379141899b ]
ice driver requires a programmable pipeline firmware package in order to have a support for advanced features. Otherwise, driver falls back to so called 'safe mode'. For that mode, ndo_bpf callback is not exposed and when user tries to load XDP program, the following happens:
$ sudo ./xdp1 enp179s0f1 libbpf: Kernel error message: Underlying driver does not support XDP in native mode link set xdp fd failed
which is sort of confusing, as there is a native XDP support, but not in the current mode. Improve the user experience by providing the specific ndo_bpf callback dedicated for safe mode which will make use of extack to explicitly let the user know that the DDP package is missing and that's the reason that the XDP can't be loaded onto interface currently.
--- drivers/net/ethernet/intel/ice/ice_main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/net/ethernet/intel/ice/ice_main.c +15 -0
@@ -2554,6 +2554,20 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,return (ret || xdp_ring_err) ? -ENOMEM :0 ; } +/** +* ice_xdp_safe_mode - XDP handler for safe mode +* @dev: netdevice +* @xdp: XDP command +*/ +static int ice_xdp_safe_mode (struct net_device __always_unused *dev, +struct netdev_bpf *xdp) +{ +NL_SET_ERR_MSG_MOD (xdp->extack, +"Please provide working DDP firmware package in order to use XDP\n" +"Refer to Documentation/networking/device_drivers/ethernet/intel/ice.rst" ); +return -EOPNOTSUPP ; +} +/** * ice_xdp - implements XDP handler * @dev: netdevice
@@ -6805,6 +6819,7 @@ static const struct net_device_ops ice_netdev_safe_mode_ops = { .ndo_change_mtu = ice_change_mtu, .ndo_get_stats64 = ice_get_stats64, .ndo_tx_timeout = ice_tx_timeout, + .ndo_bpf = ice_xdp_safe_mode, };static const struct net_device_ops ice_netdev_ops = {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 28/178 ice: parameterize functions responsible for Tx ring management
In reply to Greg Kroah-HartmanFrom: Maciej Fijalkowski <[email protected]>
[ Upstream commit 2e84f6b3773f43263124c76499c0c4ec3f40aa9b ]
Commit ae15e0ba1b33 ("ice: Change number of XDP Tx queues to match number of Rx queues") tried to address the incorrect setting of XDP queue count that was based on the Tx queue count, whereas in theory we should provide the XDP queue per Rx queue. However, the routines that setup and destroy the set of Tx resources are still based on the vsi->num_txq.
Ice supports the asynchronous Tx/Rx queue count, so for a setup where vsi->num_txq > vsi->num_rxq, ice_vsi_stop_tx_rings and ice_vsi_cfg_txqs will be accessing the vsi->xdp_rings out of the bounds.
Parameterize two mentioned functions so they get the size of Tx resources array as the input.
--- drivers/net/ethernet/intel/ice/ice_lib.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/net/ethernet/intel/ice/ice_lib.c +10 -8
@@ -1715,12 +1715,13 @@ setup_rings:* ice_vsi_cfg_txqs - Configure the VSI for Tx * @vsi: the VSI being configured * @rings: Tx ring array to be configured +* @count: number of Tx ring array elements * * Return 0 on success and a negative value on error * Configure the Tx VSI for operation. */ static int -ice_vsi_cfg_txqs (struct ice_vsi *vsi,struct ice_ring **rings) +ice_vsi_cfg_txqs (struct ice_vsi *vsi,struct ice_ring **rings,u16 count) {struct ice_aqc_add_tx_qgrp *qg_buf;u16 q_idx =0 ;
@@ -1732,7 +1733,7 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings) qg_buf->num_txqs =1 ; -for (q_idx =0 ; q_idx < vsi->num_txq; q_idx++) { +for (q_idx =0 ; q_idx < count; q_idx++) { err =ice_vsi_cfg_txq (vsi, rings[q_idx], qg_buf);if (err) goto err_cfg_txqs;
@@ -1752,7 +1753,7 @@ err_cfg_txqs:*/ int ice_vsi_cfg_lan_txqs (struct ice_vsi *vsi) { -return ice_vsi_cfg_txqs (vsi, vsi->tx_rings); +return ice_vsi_cfg_txqs (vsi, vsi->tx_rings, vsi->num_txq); }/**
@@ -1767,7 +1768,7 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)int ret;int i; - ret =ice_vsi_cfg_txqs (vsi, vsi->xdp_rings); + ret =ice_vsi_cfg_txqs (vsi, vsi->xdp_rings, vsi->num_xdp_txq);if (ret)return ret;
@@ -1965,17 +1966,18 @@ int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi)* @rst_src: reset source * @rel_vmvf_num: Relative ID of VF/VM * @rings: Tx ring array to be stopped +* @count: number of Tx ring array elements */ static int ice_vsi_stop_tx_rings (struct ice_vsi *vsi,enum ice_disq_rst_src rst_src, -u16 rel_vmvf_num,struct ice_ring **rings) +u16 rel_vmvf_num,struct ice_ring **rings,u16 count) {u16 q_idx;if (vsi->num_txq >ICE_LAN_TXQ_MAX_QDIS )return -EINVAL ; -for (q_idx =0 ; q_idx < vsi->num_txq; q_idx++) { +for (q_idx =0 ; q_idx < count; q_idx++) {struct ice_txq_meta txq_meta = { };int status;
@@ -2003,7 +2005,7 @@ int ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, u16 rel_vmvf_num) { - return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings); + return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings, vsi->num_txq); }/**
@@ -2012,7 +2014,7 @@ ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,*/ int ice_vsi_stop_xdp_tx_rings (struct ice_vsi *vsi) { -return ice_vsi_stop_tx_rings (vsi,ICE_NO_RESET ,0 , vsi->xdp_rings); +return ice_vsi_stop_tx_rings (vsi,ICE_NO_RESET ,0 , vsi->xdp_rings, vsi->num_xdp_txq); }/**
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 29/178 udp: fix race between close() and udp_abort()
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit a8b897c7bcd47f4147d066e22cc01d1026d7640e ]
Kaustubh reported and diagnosed a panic in udp_lib_lookup(). The root cause is udp_abort() racing with close(). Both racing functions acquire the socket lock, but udp{v6}_destroy_sock() release it before performing destructive actions.
We can't easily extend the socket lock scope to avoid the race, instead use the SOCK_DEAD flag to prevent udp_abort from doing any action when the critical race happens.
--- net/ipv4/udp.c | 10 ++++++++++ net/ipv6/udp.c | 3 +++ 2 files changed, 13 insertions(+)
net/ipv4/udp.c +10 -0
@@ -2576,6 +2576,9 @@ void udp_destroy_sock(struct sock *sk) {struct udp_sock *up =udp_sk (sk);bool slow =lock_sock_fast (sk); + +/* protects from races with udp_abort() */ +sock_set_flag (sk,SOCK_DEAD );udp_flush_pending_frames (sk);unlock_sock_fast (sk, slow);if (static_branch_unlikely (&udp_encap_needed_key)) {
@@ -2826,10 +2829,17 @@ int udp_abort(struct sock *sk, int err) {lock_sock (sk); +/* udp{v6}_destroy_sock() sets it under the sk lock, avoid racing +* with close() +*/ +if (sock_flag (sk,SOCK_DEAD )) + goto out; + sk->sk_err = err; sk->sk_error_report (sk);__udp_disconnect (sk,0 ); +out:release_sock (sk);return 0 ;
net/ipv6/udp.c +3 -0
@@ -1597,6 +1597,9 @@ void udpv6_destroy_sock(struct sock *sk) {struct udp_sock *up =udp_sk (sk);lock_sock (sk); + +/* protects from races with udp_abort() */ +sock_set_flag (sk,SOCK_DEAD );udp_v6_flush_pending_frames (sk);release_sock (sk);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 30/178 rtnetlink: Fix regression in bridge VLAN configuration
In reply to Greg Kroah-HartmanFrom: Ido Schimmel <[email protected]>
[ Upstream commit d2e381c4963663bca6f30c3b996fa4dbafe8fcb5 ]
Cited commit started returning errors when notification info is not filled by the bridge driver, resulting in the following regression:
# ip link add name br1 type bridge vlan_filtering 1 # bridge vlan add dev br1 vid 555 self pvid untagged RTNETLINK answers: Invalid argument
As long as the bridge driver does not fill notification info for the bridge device itself, an empty notification should not be considered as an error. This is explained in commit 59ccaaaa49b5 ("bridge: dont send notification when skb->len == 0 in rtnl_bridge_notify").
Fix by removing the error and add a comment to avoid future bugs.
--- net/core/rtnetlink.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
net/core/rtnetlink.c +5 -3
@@ -4833,10 +4833,12 @@ static int rtnl_bridge_notify(struct net_device *dev)if (err <0 ) goto errout; -if (!skb->len) { - err = -EINVAL ; +/* Notification info is only filled for bridge ports, not the bridge +* device itself. Therefore, a zero notification length is valid and +* should not result in an error. +*/ +if (!skb->len) goto errout; - }rtnl_notify (skb, net,0 ,RTNLGRP_LINK ,NULL ,GFP_ATOMIC );return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 31/178 net/sched: act_ct: handle DNAT tuple collision
In reply to Greg Kroah-HartmanFrom: Marcelo Ricardo Leitner <[email protected]>
[ Upstream commit 13c62f5371e3eb4fc3400cfa26e64ca75f888008 ]
This this the counterpart of 8aa7b526dc0b ("openvswitch: handle DNAT tuple collision") for act_ct. From that commit changelog:
"""
With multiple DNAT rules it's possible that after destination translation the resulting tuples collide.
...
Netfilter handles this case by allocating a null binding for SNAT at egress by default. Perform the same operation in openvswitch for DNAT if no explicit SNAT is requested by the user and allocate a null binding for SNAT for packets in the "original" direction.
"""
--- net/sched/act_ct.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
net/sched/act_ct.c +13 -8
@@ -904,14 +904,19 @@ static int tcf_ct_act_nat(struct sk_buff *skb, } err =ct_nat_execute (skb, ct, ctinfo, range, maniptype); -if (err ==NF_ACCEPT && - ct->status &IPS_SRC_NAT && ct->status &IPS_DST_NAT ) { -if (maniptype ==NF_NAT_MANIP_SRC ) - maniptype =NF_NAT_MANIP_DST ; -else - maniptype =NF_NAT_MANIP_SRC ; - - err =ct_nat_execute (skb, ct, ctinfo, range, maniptype); +if (err ==NF_ACCEPT && ct->status &IPS_DST_NAT ) { +if (ct->status &IPS_SRC_NAT ) { +if (maniptype ==NF_NAT_MANIP_SRC ) + maniptype =NF_NAT_MANIP_DST ; +else + maniptype =NF_NAT_MANIP_SRC ; + + err =ct_nat_execute (skb, ct, ctinfo, range, + maniptype); + }else if (CTINFO2DIR (ctinfo) ==IP_CT_DIR_ORIGINAL ) { + err =ct_nat_execute (skb, ct, ctinfo,NULL , +NF_NAT_MANIP_SRC ); + } }return err;#else
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 32/178 net/mlx5e: Fix use-after-free of encap entry in neigh update handler
In reply to Greg Kroah-HartmanFrom: Vlad Buslov <[email protected]>
[ Upstream commit fb1a3132ee1ac968316e45d21a48703a6db0b6c3 ]
Function mlx5e_rep_neigh_update() wasn't updated to accommodate rtnl lock removal from TC filter update path and properly handle concurrent encap entry insertion/deletion which can lead to following use-after-free:
[23827.464923] ================================================================== [23827.469446] BUG: KASAN: use-after-free in mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.470971] Read of size 4 at addr ffff8881d132228c by task kworker/u20:6/21635 [23827.472251] [23827.472615] CPU: 9 PID: 21635 Comm: kworker/u20:6 Not tainted 5.13.0-rc3+ #5 [23827.473788] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [23827.475639] Workqueue: mlx5e mlx5e_rep_neigh_update [mlx5_core] [23827.476731] Call Trace: [23827.477260] dump_stack+0xbb/0x107 [23827.477906] print_address_description.constprop.0+0x18/0x140 [23827.478896] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.479879] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.480905] kasan_report.cold+0x7c/0xd8 [23827.481701] ? mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.482744] kasan_check_range+0x145/0x1a0 [23827.493112] mlx5e_encap_take+0x72/0x140 [mlx5_core] [23827.494054] ? mlx5e_tc_tun_encap_info_equal_generic+0x140/0x140 [mlx5_core] [23827.495296] mlx5e_rep_neigh_update+0x41e/0x5e0 [mlx5_core] [23827.496338] ? mlx5e_rep_neigh_entry_release+0xb80/0xb80 [mlx5_core] [23827.497486] ? read_word_at_a_time+0xe/0x20 [23827.498250] ? strscpy+0xa0/0x2a0 [23827.498889] process_one_work+0x8ac/0x14e0 [23827.499638] ? lockdep_hardirqs_on_prepare+0x400/0x400 [23827.500537] ? pwq_dec_nr_in_flight+0x2c0/0x2c0 [23827.501359] ? rwlock_bug.part.0+0x90/0x90 [23827.502116] worker_thread+0x53b/0x1220 [23827.502831] ? process_one_work+0x14e0/0x14e0 [23827.503627] kthread+0x328/0x3f0 [23827.504254] ? _raw_spin_unlock_irq+0x24/0x40 [23827.505065] ? __kthread_bind_mask+0x90/0x90 [23827.505912] ret_from_fork+0x1f/0x30 [23827.506621] [23827.506987] Allocated by task 28248: [23827.507694] kasan_save_stack+0x1b/0x40 [23827.508476] __kasan_kmalloc+0x7c/0x90 [23827.509197] mlx5e_attach_encap+0xde1/0x1d40 [mlx5_core] [23827.510194] mlx5e_tc_add_fdb_flow+0x397/0xc40 [mlx5_core] [23827.511218] __mlx5e_add_fdb_flow+0x519/0xb30 [mlx5_core] [23827.512234] mlx5e_configure_flower+0x191c/0x4870 [mlx5_core] [23827.513298] tc_setup_cb_add+0x1d5/0x420 [23827.514023] fl_hw_replace_filter+0x382/0x6a0 [cls_flower] [23827.514975] fl_change+0x2ceb/0x4a51 [cls_flower] [23827.515821] tc_new_tfilter+0x89a/0x2070 [23827.516548] rtnetlink_rcv_msg+0x644/0x8c0 [23827.517300] netlink_rcv_skb+0x11d/0x340 [23827.518021] netlink_unicast+0x42b/0x700 [23827.518742] netlink_sendmsg+0x743/0xc20 [23827.519467] sock_sendmsg+0xb2/0xe0 [23827.520131] ____sys_sendmsg+0x590/0x770 [23827.520851] ___sys_sendmsg+0xd8/0x160 [23827.521552] __sys_sendmsg+0xb7/0x140 [23827.522238] do_syscall_64+0x3a/0x70 [23827.522907] entry_SYSCALL_64_after_hwframe+0x44/0xae [23827.523797] [23827.524163] Freed by task 25948: [23827.524780] kasan_save_stack+0x1b/0x40 [23827.525488] kasan_set_track+0x1c/0x30 [23827.526187] kasan_set_free_info+0x20/0x30 [23827.526968] __kasan_slab_free+0xed/0x130 [23827.527709] slab_free_freelist_hook+0xcf/0x1d0 [23827.528528] kmem_cache_free_bulk+0x33a/0x6e0 [23827.529317] kfree_rcu_work+0x55f/0xb70 [23827.530024] process_one_work+0x8ac/0x14e0 [23827.530770] worker_thread+0x53b/0x1220 [23827.531480] kthread+0x328/0x3f0 [23827.532114] ret_from_fork+0x1f/0x30 [23827.532785] [23827.533147] Last potentially related work creation: [23827.534007] kasan_save_stack+0x1b/0x40 [23827.534710] kasan_record_aux_stack+0xab/0xc0 [23827.535492] kvfree_call_rcu+0x31/0x7b0 [23827.536206] mlx5e_tc_del_fdb_flow+0x577/0xef0 [mlx5_core] [23827.537305] mlx5e_flow_put+0x49/0x80 [mlx5_core] [23827.538290] mlx5e_delete_flower+0x6d1/0xe60 [mlx5_core] [23827.539300] tc_setup_cb_destroy+0x18e/0x2f0 [23827.540144] fl_hw_destroy_filter+0x1d2/0x310 [cls_flower] [23827.541148] __fl_delete+0x4dc/0x660 [cls_flower] [23827.541985] fl_delete+0x97/0x160 [cls_flower] [23827.542782] tc_del_tfilter+0x7ab/0x13d0 [23827.543503] rtnetlink_rcv_msg+0x644/0x8c0 [23827.544257] netlink_rcv_skb+0x11d/0x340 [23827.544981] netlink_unicast+0x42b/0x700 [23827.545700] netlink_sendmsg+0x743/0xc20 [23827.546424] sock_sendmsg+0xb2/0xe0 [23827.547084] ____sys_sendmsg+0x590/0x770 [23827.547850] ___sys_sendmsg+0xd8/0x160 [23827.548606] __sys_sendmsg+0xb7/0x140 [23827.549303] do_syscall_64+0x3a/0x70 [23827.549969] entry_SYSCALL_64_after_hwframe+0x44/0xae [23827.550853] [23827.551217] The buggy address belongs to the object at ffff8881d1322200 [23827.551217] which belongs to the cache kmalloc-256 of size 256 [23827.553341] The buggy address is located 140 bytes inside of [23827.553341] 256-byte region [ffff8881d1322200, ffff8881d1322300) [23827.555747] The buggy address belongs to the page: [23827.556847] page:00000000898762aa refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d1320 [23827.558651] head:00000000898762aa order:2 compound_mapcount:0 compound_pincount:0 [23827.559961] flags: 0x2ffff800010200(slab|head|node=0|zone=2|lastcpupid=0x1ffff) [23827.561243] raw: 002ffff800010200 dead000000000100 dead000000000122 ffff888100042b40 [23827.562653] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000 [23827.564112] page dumped because: kasan: bad access detected [23827.565439] [23827.565932] Memory state around the buggy address: [23827.566917] ffff8881d1322180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.568485] ffff8881d1322200: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [23827.569818] >ffff8881d1322280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [23827.571143] ^ [23827.571879] ffff8881d1322300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.573283] ffff8881d1322380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [23827.574654] ==================================================================
Most of the necessary logic is already correctly implemented by mlx5e_get_next_valid_encap() helper that is used in neigh stats update handler. Make the handler generic by renaming it to mlx5e_get_next_matching_encap() and use callback to test whether flow is matching instead of hardcoded check for 'valid' flag value. Implement mlx5e_get_next_valid_encap() by calling mlx5e_get_next_matching_encap() with callback that tests encap MLX5_ENCAP_ENTRY_VALID flag. Implement new mlx5e_get_next_init_encap() helper by calling mlx5e_get_next_matching_encap() with callback that tests encap completion result to be non-error and use it in mlx5e_rep_neigh_update() to safely iterate over nhe->encap_list.
Remove encap completion logic from mlx5e_rep_update_flows() since the encap entries passed to this function are already guaranteed to be properly initialized by similar code in mlx5e_get_next_init_encap().
--- .../mellanox/mlx5/core/en/rep/neigh.c | 15 ++++----- .../ethernet/mellanox/mlx5/core/en/rep/tc.c | 6 +--- .../mellanox/mlx5/core/en/tc_tun_encap.c | 33 +++++++++++++++++-- .../net/ethernet/mellanox/mlx5/core/en_tc.h | 3 ++ 4 files changed, 40 insertions(+), 17 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c +6 -9
@@ -129,10 +129,9 @@ static void mlx5e_rep_neigh_update(struct work_struct *work) work);struct mlx5e_neigh_hash_entry *nhe = update_work->nhe;struct neighbour *n = update_work->n; +struct mlx5e_encap_entry *e =NULL ;bool neigh_connected, same_dev; -struct mlx5e_encap_entry *e;unsigned char ha[ETH_ALEN ]; -struct mlx5e_priv *priv;u8 nud_state, dead;rtnl_lock ();
@@ -156,14 +155,12 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)if (!same_dev) goto out; -list_for_each_entry (e, &nhe->encap_list, encap_list) { -if (!mlx5e_encap_take (e)) -continue ; +/* mlx5e_get_next_init_encap() releases previous encap before returning +* the next one. +*/ +while ((e =mlx5e_get_next_init_encap (nhe, e)) !=NULL ) +mlx5e_rep_update_flows (netdev_priv (e->out_dev), e, neigh_connected, ha); - priv =netdev_priv (e->out_dev); -mlx5e_rep_update_flows (priv, e, neigh_connected, ha); -mlx5e_encap_put (priv, e); - } out:rtnl_unlock ();mlx5e_release_neigh_update_work (update_work);
drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c +1 -5
@@ -93,13 +93,9 @@ void mlx5e_rep_update_flows(struct mlx5e_priv *priv,ASSERT_RTNL (); -/* wait for encap to be fully initialized */ -wait_for_completion (&e->res_ready); -mutex_lock (&esw->offloads.encap_tbl_lock); encap_connected = !!(e->flags &MLX5_ENCAP_ENTRY_VALID ); -if (e->compl_result <0 || (encap_connected == neigh_connected && -ether_addr_equal (e->h_dest, ha))) +if (encap_connected == neigh_connected &ðer_addr_equal (e->h_dest, ha)) goto unlock;mlx5e_take_all_encap_flows (e, &flow_list);
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +30 -3
@@ -250,9 +250,12 @@ static void mlx5e_take_all_route_decap_flows(struct mlx5e_route_entry *r,mlx5e_take_tmp_flow (flow, flow_list,0 ); } +typedef bool (match_cb )(struct mlx5e_encap_entry *); +static struct mlx5e_encap_entry * -mlx5e_get_next_valid_encap (struct mlx5e_neigh_hash_entry *nhe, -struct mlx5e_encap_entry *e) +mlx5e_get_next_matching_encap (struct mlx5e_neigh_hash_entry *nhe, +struct mlx5e_encap_entry *e, +match_cb match) {struct mlx5e_encap_entry *next =NULL ;
@@ -287,7 +290,7 @@ retry:/* wait for encap to be fully initialized */ wait_for_completion (&next->res_ready);/* continue searching if encap entry is not in valid state after completion */ -if (!(next->flags &MLX5_ENCAP_ENTRY_VALID )) { +if (!match (next)) { e = next; goto retry; }
@@ -295,6 +298,30 @@ retry:return next; } +static bool mlx5e_encap_valid (struct mlx5e_encap_entry *e) +{ +return e->flags &MLX5_ENCAP_ENTRY_VALID ; +} + +static struct mlx5e_encap_entry * +mlx5e_get_next_valid_encap (struct mlx5e_neigh_hash_entry *nhe, +struct mlx5e_encap_entry *e) +{ +return mlx5e_get_next_matching_encap (nhe, e, mlx5e_encap_valid); +} + +static bool mlx5e_encap_initialized (struct mlx5e_encap_entry *e) +{ +return e->compl_result >=0 ; +} + +struct mlx5e_encap_entry * +mlx5e_get_next_init_encap (struct mlx5e_neigh_hash_entry *nhe, +struct mlx5e_encap_entry *e) +{ +return mlx5e_get_next_matching_encap (nhe, e, mlx5e_encap_initialized); +} +void mlx5e_tc_update_neigh_used_value (struct mlx5e_neigh_hash_entry *nhe) {struct mlx5e_neigh *m_neigh = &nhe->m_neigh;
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h +3 -0
@@ -178,6 +178,9 @@ void mlx5e_take_all_encap_flows(struct mlx5e_encap_entry *e, struct list_head *fvoid mlx5e_put_flow_list (struct mlx5e_priv *priv,struct list_head *flow_list);struct mlx5e_neigh_hash_entry ; +struct mlx5e_encap_entry * +mlx5e_get_next_init_encap (struct mlx5e_neigh_hash_entry *nhe, +struct mlx5e_encap_entry *e);void mlx5e_tc_update_neigh_used_value (struct mlx5e_neigh_hash_entry *nhe);void mlx5e_tc_reoffload_flows_work (struct work_struct *work);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 33/178 net/mlx5e: Remove dependency in IPsec initialization flows
In reply to Greg Kroah-HartmanFrom: Huy Nguyen <[email protected]>
[ Upstream commit 8ad893e516a77209a1818a2072d2027d87db809f ]
Currently, IPsec feature is disabled because mlx5e_build_nic_netdev is required to be called after mlx5e_ipsec_init. This requirement is invalid as mlx5e_build_nic_netdev and mlx5e_ipsec_init initialize independent resources.
Remove ipsec pointer check in mlx5e_build_nic_netdev so that the two functions can be called at any order.
--- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 --- 1 file changed, 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +0 -3
@@ -532,9 +532,6 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv)struct mlx5_core_dev *mdev = priv->mdev;struct net_device *netdev = priv->netdev; -if (!priv->ipsec) -return ; -if (!(mlx5_accel_ipsec_device_caps (mdev) &MLX5_ACCEL_IPSEC_CAP_ESP ) || !MLX5_CAP_ETH (mdev, swp)) {mlx5_core_dbg (mdev,"mlx5e: ESP and SWP offload not supported\n" );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 34/178 net/mlx5e: Fix page reclaim for dead peer hairpin
In reply to Greg Kroah-HartmanFrom: Dima Chumak <[email protected]>
[ Upstream commit a3e5fd9314dfc4314a9567cde96e1aef83a7458a ]
When adding a hairpin flow, a firmware-side send queue is created for the peer net device, which claims some host memory pages for its internal ring buffer. If the peer net device is removed/unbound before the hairpin flow is deleted, then the send queue is not destroyed which leads to a stack trace on pci device remove:
[ 748.005230] mlx5_core 0000:08:00.2: wait_func:1094:(pid 12985): MANAGE_PAGES(0x108) timeout. Will cause a leak of a command resource [ 748.005231] mlx5_core 0000:08:00.2: reclaim_pages:514:(pid 12985): failed reclaiming pages: err -110 [ 748.001835] mlx5_core 0000:08:00.2: mlx5_reclaim_root_pages:653:(pid 12985): failed reclaiming pages (-110) for func id 0x0 [ 748.002171] ------------[ cut here ]------------ [ 748.001177] FW pages counter is 4 after reclaiming all pages [ 748.001186] WARNING: CPU: 1 PID: 12985 at drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c:685 mlx5_reclaim_startup_pages+0x34b/0x460 [mlx5_core] [ +0.002771] Modules linked in: cls_flower mlx5_ib mlx5_core ptp pps_core act_mirred sch_ingress openvswitch nsh xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xt_addrtype iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter rpcrdma rdma_ucm ib_iser libiscsi scsi_transport_iscsi rdma_cm ib_umad ib_ipoib iw_cm ib_cm ib_uverbs ib_core overlay fuse [last unloaded: pps_core] [ 748.007225] CPU: 1 PID: 12985 Comm: tee Not tainted 5.12.0+ #1 [ 748.001376] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [ 748.002315] RIP: 0010:mlx5_reclaim_startup_pages+0x34b/0x460 [mlx5_core] [ 748.001679] Code: 28 00 00 00 0f 85 22 01 00 00 48 81 c4 b0 00 00 00 31 c0 5b 5d 41 5c 41 5d 41 5e 41 5f c3 48 c7 c7 40 cc 19 a1 e8 9f 71 0e e2 <0f> 0b e9 30 ff ff ff 48 c7 c7 a0 cc 19 a1 e8 8c 71 0e e2 0f 0b e9 [ 748.003781] RSP: 0018:ffff88815220faf8 EFLAGS: 00010286 [ 748.001149] RAX: 0000000000000000 RBX: ffff8881b4900280 RCX: 0000000000000000 [ 748.001445] RDX: 0000000000000027 RSI: 0000000000000004 RDI: ffffed102a441f51 [ 748.001614] RBP: 00000000000032b9 R08: 0000000000000001 R09: ffffed1054a15ee8 [ 748.001446] R10: ffff8882a50af73b R11: ffffed1054a15ee7 R12: fffffbfff07c1e30 [ 748.001447] R13: dffffc0000000000 R14: ffff8881b492cba8 R15: 0000000000000000 [ 748.001429] FS: 00007f58bd08b580(0000) GS:ffff8882a5080000(0000) knlGS:0000000000000000 [ 748.001695] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 748.001309] CR2: 000055a026351740 CR3: 00000001d3b48006 CR4: 0000000000370ea0 [ 748.001506] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 748.001483] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 748.001654] Call Trace: [ 748.000576] ? mlx5_satisfy_startup_pages+0x290/0x290 [mlx5_core] [ 748.001416] ? mlx5_cmd_teardown_hca+0xa2/0xd0 [mlx5_core] [ 748.001354] ? mlx5_cmd_init_hca+0x280/0x280 [mlx5_core] [ 748.001203] mlx5_function_teardown+0x30/0x60 [mlx5_core] [ 748.001275] mlx5_uninit_one+0xa7/0xc0 [mlx5_core] [ 748.001200] remove_one+0x5f/0xc0 [mlx5_core] [ 748.001075] pci_device_remove+0x9f/0x1d0 [ 748.000833] device_release_driver_internal+0x1e0/0x490 [ 748.001207] unbind_store+0x19f/0x200 [ 748.000942] ? sysfs_file_ops+0x170/0x170 [ 748.001000] kernfs_fop_write_iter+0x2bc/0x450 [ 748.000970] new_sync_write+0x373/0x610 [ 748.001124] ? new_sync_read+0x600/0x600 [ 748.001057] ? lock_acquire+0x4d6/0x700 [ 748.000908] ? lockdep_hardirqs_on_prepare+0x400/0x400 [ 748.001126] ? fd_install+0x1c9/0x4d0 [ 748.000951] vfs_write+0x4d0/0x800 [ 748.000804] ksys_write+0xf9/0x1d0 [ 748.000868] ? __x64_sys_read+0xb0/0xb0 [ 748.000811] ? filp_open+0x50/0x50 [ 748.000919] ? syscall_enter_from_user_mode+0x1d/0x50 [ 748.001223] do_syscall_64+0x3f/0x80 [ 748.000892] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 748.001026] RIP: 0033:0x7f58bcfb22f7 [ 748.000944] Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24 [ 748.003925] RSP: 002b:00007fffd7f2aaa8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 748.001732] RAX: ffffffffffffffda RBX: 000000000000000d RCX: 00007f58bcfb22f7 [ 748.001426] RDX: 000000000000000d RSI: 00007fffd7f2abc0 RDI: 0000000000000003 [ 748.001746] RBP: 00007fffd7f2abc0 R08: 0000000000000000 R09: 0000000000000001 [ 748.001631] R10: 00000000000001b6 R11: 0000000000000246 R12: 000000000000000d [ 748.001537] R13: 00005597ac2c24a0 R14: 000000000000000d R15: 00007f58bd084700 [ 748.001564] irq event stamp: 0 [ 748.000787] hardirqs last enabled at (0): [<0000000000000000>] 0x0 [ 748.001399] hardirqs last disabled at (0): [<ffffffff813132cf>] copy_process+0x146f/0x5eb0 [ 748.001854] softirqs last enabled at (0): [<ffffffff8131330e>] copy_process+0x14ae/0x5eb0 [ 748.013431] softirqs last disabled at (0): [<0000000000000000>] 0x0 [ 748.001492] ---[ end trace a6fabd773d1c51ae ]---
Fix by destroying the send queue of a hairpin peer net device that is being removed/unbound, which returns the allocated ring buffer pages to the host.
--- .../net/ethernet/mellanox/mlx5/core/en_tc.c | 2 +- .../ethernet/mellanox/mlx5/core/transobj.c | 30 +++++++++++++++---- include/linux/mlx5/transobj.h | 1 + 3 files changed, 26 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +1 -1
@@ -4622,7 +4622,7 @@ static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,list_for_each_entry_safe (hpe, tmp, &init_wait_list, dead_peer_wait_list) {wait_for_completion (&hpe->res_ready);if (!IS_ERR_OR_NULL (hpe->hp) && hpe->peer_vhca_id == peer_vhca_id) - hpe->hp->pair->peer_gone = true; +mlx5_core_hairpin_clear_dead_peer (hpe->hp->pair);mlx5e_hairpin_put (priv, hpe); }
drivers/net/ethernet/mellanox/mlx5/core/transobj.c +24 -6
@@ -424,6 +424,15 @@ err_modify_sq:return err; } +static void mlx5_hairpin_unpair_peer_sq (struct mlx5_hairpin *hp) +{ +int i; + +for (i =0 ; i < hp->num_channels; i++) +mlx5_hairpin_modify_sq (hp->peer_mdev, hp->sqn[i],MLX5_SQC_STATE_RDY , +MLX5_SQC_STATE_RST ,0 ,0 ); +} +static void mlx5_hairpin_unpair_queues (struct mlx5_hairpin *hp) {int i;
@@ -432,13 +441,9 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)for (i =0 ; i < hp->num_channels; i++)mlx5_hairpin_modify_rq (hp->func_mdev, hp->rqn[i],MLX5_RQC_STATE_RDY ,MLX5_RQC_STATE_RST ,0 ,0 ); -/* unset peer SQs */ -if (hp->peer_gone) -return ; -for (i =0 ; i < hp->num_channels; i++) -mlx5_hairpin_modify_sq (hp->peer_mdev, hp->sqn[i],MLX5_SQC_STATE_RDY , -MLX5_SQC_STATE_RST ,0 ,0 ); +if (!hp->peer_gone) +mlx5_hairpin_unpair_peer_sq (hp); } struct mlx5_hairpin *
@@ -485,3 +490,16 @@ void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp)mlx5_hairpin_destroy_queues (hp);kfree (hp); } + +void mlx5_core_hairpin_clear_dead_peer (struct mlx5_hairpin *hp) +{ +int i; + +mlx5_hairpin_unpair_peer_sq (hp); + +/* destroy peer SQ */ +for (i =0 ; i < hp->num_channels; i++) +mlx5_core_destroy_sq (hp->peer_mdev, hp->sqn[i]); + + hp->peer_gone = true; +}
include/linux/mlx5/transobj.h +1 -0
@@ -85,4 +85,5 @@ mlx5_core_hairpin_create(struct mlx5_core_dev *func_mdev, struct mlx5_hairpin_params *params);void mlx5_core_hairpin_destroy (struct mlx5_hairpin *pair); +void mlx5_core_hairpin_clear_dead_peer (struct mlx5_hairpin *hp);#endif /* __TRANSOBJ_H__ */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 35/178 net/mlx5: Consider RoCE cap before init RDMA resources
In reply to Greg Kroah-HartmanFrom: Maor Gottlieb <[email protected]>
[ Upstream commit c189716b2a7c1d2d8658e269735273caa1c38b54 ]
Check if RoCE is supported by the device before enable it in the vport context and create all the RDMA steering objects.
--- drivers/net/ethernet/mellanox/mlx5/core/rdma.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/rdma.c +3 -0
@@ -156,6 +156,9 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) {int err; +if (!MLX5_CAP_GEN (dev, roce)) +return ; + err =mlx5_nic_vport_enable_roce (dev);if (err) {mlx5_core_err (dev,"Failed to enable RoCE: %d\n" , err);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 36/178 net/mlx5: DR, Dont use SW steering when RoCE is not supported
In reply to Greg Kroah-HartmanFrom: Maor Gottlieb <[email protected]>
[ Upstream commit 4aaf96ac8b45d8e2e019b6b53cce65a73c4ace2c ]
SW steering uses RC QP to write/read to/from ICM, hence it's not supported when RoCE is not supported as well.
--- .../net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h +5 -4
@@ -124,10 +124,11 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action);static inline bool mlx5dr_is_supported (struct mlx5_core_dev *dev) { -return MLX5_CAP_ESW_FLOWTABLE_FDB (dev, sw_owner) || - (MLX5_CAP_ESW_FLOWTABLE_FDB (dev, sw_owner_v2) && - (MLX5_CAP_GEN (dev, steering_format_version) <= -MLX5_STEERING_FORMAT_CONNECTX_6DX )); +return MLX5_CAP_GEN (dev, roce) && + (MLX5_CAP_ESW_FLOWTABLE_FDB (dev, sw_owner) || + (MLX5_CAP_ESW_FLOWTABLE_FDB (dev, sw_owner_v2) && + (MLX5_CAP_GEN (dev, steering_format_version) <= +MLX5_STEERING_FORMAT_CONNECTX_6DX ))); }/* buddy functions & structure */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 37/178 Revert "net/mlx5: Arm only EQs with EQEs"
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
[ Upstream commit 7a545077cb6701957e84c7f158630bb5c984e648 ]
In the scenario described below, an EQ can remain in FIRED state which can result in missing an interrupt generation.
The scenario:
device mlx5_core driver
------ ----------------
EQ1.eqe generated
EQ1.MSI-X sent
EQ1.state = FIRED
EQ2.eqe generated
mlx5_irq()
polls - eq1_eqes()
arm eq1
polls - eq2_eqes()
arm eq2
EQ2.MSI-X sent
EQ2.state = FIRED
mlx5_irq()
polls - eq2_eqes() -- no eqes found
driver skips EQ arming;->EQ2 remains fired, misses generating interrupt.
Hence, always arm the EQ by reverting the cited commit in fixes tag.
--- drivers/net/ethernet/mellanox/mlx5/core/eq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eq.c +4 -2
@@ -136,7 +136,7 @@ static int mlx5_eq_comp_int(struct notifier_block *nb, eqe =next_eqe_sw (eq);if (!eqe) -return 0 ; + goto out; do { struct mlx5_core_cq *cq;
@@ -161,6 +161,8 @@ static int mlx5_eq_comp_int(struct notifier_block *nb, ++eq->cons_index; }while ((++num_eqes <MLX5_EQ_POLLING_BUDGET ) && (eqe =next_eqe_sw (eq))); + +out:eq_update_ci (eq,1 );if (cqn !=-1 )
@@ -248,9 +250,9 @@ static int mlx5_eq_async_int(struct notifier_block *nb, ++eq->cons_index; }while ((++num_eqes <MLX5_EQ_POLLING_BUDGET ) && (eqe =next_eqe_sw (eq))); -eq_update_ci (eq,1 ); out: +eq_update_ci (eq,1 );mlx5_eq_async_int_unlock (eq_async, recovery, &flags);return unlikely (recovery) ? num_eqes :0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 38/178 net/mlx5e: Block offload of outer header csum for UDP tunnels
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit 6d6727dddc7f93fcc155cb8d0c49c29ae0e71122 ]
The device is able to offload either the outer header csum or inner header csum. The driver utilizes the inner csum offload. Hence, block setting of tx-udp_tnl-csum-segmentation and set it to off[fixed].
--- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +3 -7
@@ -5168,13 +5168,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) }if (mlx5_vxlan_allowed (mdev->vxlan) ||mlx5_geneve_tx_allowed (mdev)) { - netdev->hw_features |=NETIF_F_GSO_UDP_TUNNEL | -NETIF_F_GSO_UDP_TUNNEL_CSUM ; - netdev->hw_enc_features |=NETIF_F_GSO_UDP_TUNNEL | -NETIF_F_GSO_UDP_TUNNEL_CSUM ; - netdev->gso_partial_features =NETIF_F_GSO_UDP_TUNNEL_CSUM ; - netdev->vlan_features |=NETIF_F_GSO_UDP_TUNNEL | -NETIF_F_GSO_UDP_TUNNEL_CSUM ; + netdev->hw_features |=NETIF_F_GSO_UDP_TUNNEL ; + netdev->hw_enc_features |=NETIF_F_GSO_UDP_TUNNEL ; + netdev->vlan_features |=NETIF_F_GSO_UDP_TUNNEL ; }if (mlx5e_tunnel_proto_supported_tx (mdev,IPPROTO_GRE )) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 39/178 net/mlx5e: Block offload of outer header csum for GRE tunnel
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit 54e1217b90486c94b26f24dcee1ee5ef5372f832 ]
The device is able to offload either the outer header csum or inner header csum. The driver utilizes the inner csum offload. So, prohibit setting of tx-gre-csum-segmentation and let it be: off[fixed].
--- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +3 -6
@@ -5174,12 +5174,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) }if (mlx5e_tunnel_proto_supported_tx (mdev,IPPROTO_GRE )) { - netdev->hw_features |=NETIF_F_GSO_GRE | -NETIF_F_GSO_GRE_CSUM ; - netdev->hw_enc_features |=NETIF_F_GSO_GRE | -NETIF_F_GSO_GRE_CSUM ; - netdev->gso_partial_features |=NETIF_F_GSO_GRE | -NETIF_F_GSO_GRE_CSUM ; + netdev->hw_features |=NETIF_F_GSO_GRE ; + netdev->hw_enc_features |=NETIF_F_GSO_GRE ; + netdev->gso_partial_features |=NETIF_F_GSO_GRE ; }if (mlx5e_tunnel_proto_supported_tx (mdev,IPPROTO_IPIP )) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 40/178 skbuff: fix incorrect msg_zerocopy copy notifications
In reply to Greg Kroah-HartmanFrom: Willem de Bruijn <[email protected]>
[ Upstream commit 3bdd5ee0ec8c14131d560da492e6df452c6fdd75 ]
msg_zerocopy signals if a send operation required copying with a flag in serr->ee.ee_code.
This field can be incorrect as of the below commit, as a result of both structs uarg and serr pointing into the same skb->cb[].
uarg->zerocopy must be read before skb->cb[] is reinitialized to hold serr. Similar to other fields len, hi and lo, use a local variable to temporarily hold the value.
This was not a problem before, when the value was passed as a function argument.
--- net/core/skbuff.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/core/skbuff.c +3 -1
@@ -1252,6 +1252,7 @@ static void __msg_zerocopy_callback(struct ubuf_info *uarg)struct sock *sk = skb->sk;struct sk_buff_head *q;unsigned long flags; +bool is_zerocopy;u32 lo, hi;u16 len;
@@ -1266,6 +1267,7 @@ static void __msg_zerocopy_callback(struct ubuf_info *uarg) len = uarg->len; lo = uarg->id; hi = uarg->id + len -1 ; + is_zerocopy = uarg->zerocopy; serr =SKB_EXT_ERR (skb);memset (serr,0 ,sizeof (*serr));
@@ -1273,7 +1275,7 @@ static void __msg_zerocopy_callback(struct ubuf_info *uarg) serr->ee.ee_origin =SO_EE_ORIGIN_ZEROCOPY ; serr->ee.ee_data = hi; serr->ee.ee_info = lo; -if (!uarg->zerocopy) +if (!is_zerocopy) serr->ee.ee_code |=SO_EE_CODE_ZEROCOPY_COPIED ; q = &sk->sk_error_queue;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 41/178 netfilter: synproxy: Fix out of bounds when parsing TCP options
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit 5fc177ab759418c9537433e63301096e733fb915 ]
The TCP option parser in synproxy (synproxy_parse_options) could read one byte out of bounds. When the length is 1, the execution flow gets into the loop, reads one byte of the opcode, and if the opcode is neither TCPOPT_EOL nor TCPOPT_NOP, it reads one more byte, which exceeds the length of 1.
This fix is inspired by commit 9609dad263f8 ("ipv4: tcp_input: fix stack out of bounds when parsing TCP options.").
v2 changes:
Added an early return when length < 0 to avoid calling skb_header_pointer with negative length.
--- net/netfilter/nf_synproxy_core.c | 5 +++++ 1 file changed, 5 insertions(+)
net/netfilter/nf_synproxy_core.c +5 -0
@@ -31,6 +31,9 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff,int length = (th->doff *4 ) -sizeof (*th);u8 buf[40 ], *ptr; +if (unlikely (length <0 )) +return false; + ptr =skb_header_pointer (skb, doff +sizeof (*th), length, buf);if (ptr ==NULL )return false;
@@ -47,6 +50,8 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, length--;continue ;default : +if (length <2 ) +return true; opsize = *ptr++;if (opsize <2 )return true;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 42/178 mptcp: Fix out of bounds when parsing TCP options
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit 07718be265680dcf496347d475ce1a5442f55ad7 ]
The TCP option parser in mptcp (mptcp_get_options) could read one byte out of bounds. When the length is 1, the execution flow gets into the loop, reads one byte of the opcode, and if the opcode is neither TCPOPT_EOL nor TCPOPT_NOP, it reads one more byte, which exceeds the length of 1.
This fix is inspired by commit 9609dad263f8 ("ipv4: tcp_input: fix stack out of bounds when parsing TCP options.").
--- net/mptcp/options.c | 2 ++ 1 file changed, 2 insertions(+)
net/mptcp/options.c +2 -0
@@ -337,6 +337,8 @@ void mptcp_get_options(const struct sk_buff *skb, length--;continue ;default : +if (length <2 ) +return ; opsize = *ptr++;if (opsize <2 )/* "silly options" */ return ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 43/178 sch_cake: Fix out of bounds when parsing TCP options and header
In reply to Greg Kroah-HartmanFrom: Maxim Mikityanskiy <[email protected]>
[ Upstream commit ba91c49dedbde758ba0b72f57ac90b06ddf8e548 ]
The TCP option parser in cake qdisc (cake_get_tcpopt and cake_tcph_may_drop) could read one byte out of bounds. When the length is 1, the execution flow gets into the loop, reads one byte of the opcode, and if the opcode is neither TCPOPT_EOL nor TCPOPT_NOP, it reads one more byte, which exceeds the length of 1.
This fix is inspired by commit 9609dad263f8 ("ipv4: tcp_input: fix stack out of bounds when parsing TCP options.").
v2 changes:
Added doff validation in cake_get_tcphdr to avoid parsing garbage as TCP header. Although it wasn't strictly an out-of-bounds access (memory was allocated), garbage values could be read where CAKE expected the TCP header if doff was smaller than 5.
--- net/sched/sch_cake.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/sched/sch_cake.c +5 -1
@@ -943,7 +943,7 @@ static struct tcphdr *cake_get_tcphdr(const struct sk_buff *skb, } tcph =skb_header_pointer (skb, offset,sizeof (_tcph), &_tcph); -if (!tcph) +if (!tcph || tcph->doff <5 )return NULL ; return skb_header_pointer(skb, offset,
@@ -967,6 +967,8 @@ static const void *cake_get_tcpopt(const struct tcphdr *tcph, length--;continue ; } +if (length <2 ) +break ; opsize = *ptr++;if (opsize <2 || opsize > length)break ;
@@ -1104,6 +1106,8 @@ static bool cake_tcph_may_drop(const struct tcphdr *tcph, length--;continue ; } +if (length <2 ) +break ; opsize = *ptr++;if (opsize <2 || opsize > length)break ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 44/178 mptcp: try harder to borrow memory from subflow under pressure
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 72f961320d5d15bfcb26dbe3edaa3f7d25fd2c8a ]
If the host is under sever memory pressure, and RX forward memory allocation for the msk fails, we try to borrow the required memory from the ingress subflow.
The current attempt is a bit flaky: if skb->truesize is less than SK_MEM_QUANTUM, the ssk will not release any memory, and the next schedule will fail again.
Instead, directly move the required amount of pages from the ssk to the msk, if available
--- net/mptcp/protocol.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/mptcp/protocol.c +6 -4
@@ -287,11 +287,13 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,/* try to fetch required memory from subflow */ if (!sk_rmem_schedule (sk, skb, skb->truesize)) { -if (ssk->sk_forward_alloc < skb->truesize) - goto drop; -__sk_mem_reclaim (ssk, skb->truesize); -if (!sk_rmem_schedule (sk, skb, skb->truesize)) +int amount =sk_mem_pages (skb->truesize) <<SK_MEM_QUANTUM_SHIFT ; + +if (ssk->sk_forward_alloc < amount) goto drop; + + ssk->sk_forward_alloc -= amount; + sk->sk_forward_alloc += amount; }/* the skb map_seq accounts for the skb offset:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 45/178 mptcp: wake-up readers only for in sequence data
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 99d1055ce2469dca3dd14be0991ff8133e25e3d0 ]
Currently we rely on the subflow->data_avail field, which is subject to races:
ssk1 skb len = 500 DSS(seq=1, len=1000, off=0) # data_avail == MPTCP_SUBFLOW_DATA_AVAIL ssk2 skb len = 500 DSS(seq = 501, len=1000) # data_avail == MPTCP_SUBFLOW_DATA_AVAIL ssk1 skb len = 500 DSS(seq = 1, len=1000, off =500) # still data_avail == MPTCP_SUBFLOW_DATA_AVAIL, # as the skb is covered by a pre-existing map, # which was in-sequence at reception time.
Instead we can explicitly check if some has been received in-sequence, propagating the info from __mptcp_move_skbs_from_subflow().
Additionally add the 'ONCE' annotation to the 'data_avail' memory access, as msk will read it outside the subflow socket lock.
--- net/mptcp/protocol.c | 33 ++++++++++++--------------------- net/mptcp/protocol.h | 1 - net/mptcp/subflow.c | 23 +++++++++-------------- 3 files changed, 21 insertions(+), 36 deletions(-)
net/mptcp/protocol.c +12 -21
@@ -689,15 +689,13 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk)/* In most cases we will be able to lock the mptcp socket. If its already * owned, we need to defer to the work queue to avoid ABBA deadlock. */ -static void move_skbs_to_msk (struct mptcp_sock *msk,struct sock *ssk) +static bool move_skbs_to_msk (struct mptcp_sock *msk,struct sock *ssk) {struct sock *sk = (struct sock *)msk;unsigned int moved =0 ;if (inet_sk_state_load (sk) ==TCP_CLOSE ) -return ; - -mptcp_data_lock (sk); +return false;__mptcp_move_skbs_from_subflow (msk, ssk, &moved);__mptcp_ofo_queue (msk);
@@ -709,7 +707,7 @@ static void move_skbs_to_msk(struct mptcp_sock *msk, struct sock *ssk)*/ if (mptcp_pending_data_fin (sk,NULL ))mptcp_schedule_work (sk); -mptcp_data_unlock (sk); +return moved >0 ; }void mptcp_data_ready (struct sock *sk,struct sock *ssk)
@@ -717,7 +715,6 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)struct mptcp_subflow_context *subflow =mptcp_subflow_ctx (ssk);struct mptcp_sock *msk =mptcp_sk (sk);int sk_rbuf, ssk_rbuf; -bool wake;/* The peer can send data while we are shutting down this * subflow at msk destruction time, but we must avoid enqueuing
@@ -726,28 +723,22 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk)if (unlikely (subflow->disposable))return ; -/* move_skbs_to_msk below can legitly clear the data_avail flag, -* but we will need later to properly woke the reader, cache its -* value -*/ - wake = subflow->data_avail ==MPTCP_SUBFLOW_DATA_AVAIL ; -if (wake) -set_bit (MPTCP_DATA_READY , &msk->flags); - ssk_rbuf =READ_ONCE (ssk->sk_rcvbuf); sk_rbuf =READ_ONCE (sk->sk_rcvbuf);if (unlikely (ssk_rbuf > sk_rbuf)) sk_rbuf = ssk_rbuf; -/* over limit? can't append more skbs to msk */ +/* over limit? can't append more skbs to msk, Also, no need to wake-up*/ if (atomic_read (&sk->sk_rmem_alloc) > sk_rbuf) - goto wake; - -move_skbs_to_msk (msk, ssk); +return ; -wake: -if (wake) +/* Wake-up the reader only for in-sequence data */ +mptcp_data_lock (sk); +if (move_skbs_to_msk (msk, ssk)) { +set_bit (MPTCP_DATA_READY , &msk->flags); sk->sk_data_ready (sk); + } +mptcp_data_unlock (sk); }void __mptcp_flush_join_list (struct mptcp_sock *msk)
@@ -850,7 +841,7 @@ static struct sock *mptcp_subflow_recv_lookup(const struct mptcp_sock *msk)sock_owned_by_me (sk);mptcp_for_each_subflow (msk, subflow) { -if (subflow->data_avail) +if (READ_ONCE (subflow->data_avail))return mptcp_subflow_tcp_sock (subflow); }
net/mptcp/protocol.h +0 -1
@@ -372,7 +372,6 @@ mptcp_subflow_rsk(const struct request_sock *rsk)enum mptcp_data_avail {MPTCP_SUBFLOW_NODATA ,MPTCP_SUBFLOW_DATA_AVAIL , -MPTCP_SUBFLOW_OOO_DATA };struct mptcp_delegated_action {
net/mptcp/subflow.c +9 -14
@@ -974,7 +974,7 @@ static bool subflow_check_data_avail(struct sock *ssk)pr_debug ("msk=%p ssk=%p data_avail=%d skb=%p" , subflow->conn, ssk, subflow->data_avail,skb_peek (&ssk->sk_receive_queue));if (!skb_peek (&ssk->sk_receive_queue)) - subflow->data_avail =0 ; +WRITE_ONCE (subflow->data_avail,0 );if (subflow->data_avail)return true;
@@ -1012,18 +1012,13 @@ static bool subflow_check_data_avail(struct sock *ssk) ack_seq =mptcp_subflow_get_mapped_dsn (subflow);pr_debug ("msk ack_seq=%llx subflow ack_seq=%llx" , old_ack, ack_seq); -if (ack_seq == old_ack) { - subflow->data_avail =MPTCP_SUBFLOW_DATA_AVAIL ; -break ; - }else if (after64 (ack_seq, old_ack)) { - subflow->data_avail =MPTCP_SUBFLOW_OOO_DATA ; -break ; +if (unlikely (before64 (ack_seq, old_ack))) { +mptcp_subflow_discard_data (ssk, skb, old_ack - ack_seq); +continue ; } -/* only accept in-sequence mapping. Old values are spurious -* retransmission -*/ -mptcp_subflow_discard_data (ssk, skb, old_ack - ack_seq); +WRITE_ONCE (subflow->data_avail,MPTCP_SUBFLOW_DATA_AVAIL ); +break ; }return true;
@@ -1041,7 +1036,7 @@ fallback: ssk->sk_error_report (ssk);tcp_set_state (ssk,TCP_CLOSE );tcp_send_active_reset (ssk,GFP_ATOMIC ); - subflow->data_avail =0 ; +WRITE_ONCE (subflow->data_avail,0 );return false; }
@@ -1051,7 +1046,7 @@ fallback: subflow->map_seq =READ_ONCE (msk->ack_seq); subflow->map_data_len = skb->len; subflow->map_subflow_seq =tcp_sk (ssk)->copied_seq - subflow->ssn_offset; - subflow->data_avail =MPTCP_SUBFLOW_DATA_AVAIL ; +WRITE_ONCE (subflow->data_avail,MPTCP_SUBFLOW_DATA_AVAIL );return true; }
@@ -1063,7 +1058,7 @@ bool mptcp_subflow_data_available(struct sock *sk)if (subflow->map_valid &&mptcp_subflow_get_map_offset (subflow) >= subflow->map_data_len) { subflow->map_valid =0 ; - subflow->data_avail =0 ; +WRITE_ONCE (subflow->data_avail,0 ); pr_debug("Done with mapping: seq=%u data_len=%u", subflow->map_subflow_seq,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 46/178 mptcp: do not warn on bad input from the network
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 61e710227e97172355d5f150d5c78c64175d9fb2 ]
warn_bad_map() produces a kernel WARN on bad input coming from the network. Use pr_debug() to avoid spamming the system log.
Additionally, when the right bound check fails, warn_bad_map() reports the wrong ssn value, let's fix it.
--- net/mptcp/subflow.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/mptcp/subflow.c +5 -5
@@ -754,10 +754,10 @@ static u64 expand_seq(u64 old_seq, u16 old_data_len, u64 seq)return seq | ((old_seq + old_data_len +1 ) &GENMASK_ULL (63 ,32 )); } -static void warn_bad_map (struct mptcp_subflow_context *subflow,u32 ssn) +static void dbg_bad_map (struct mptcp_subflow_context *subflow,u32 ssn) { -WARN_ONCE (1 ,"Bad mapping: ssn=%d map_seq=%d map_data_len=%d" , - ssn, subflow->map_subflow_seq, subflow->map_data_len); +pr_debug ("Bad mapping: ssn=%d map_seq=%d map_data_len=%d" , + ssn, subflow->map_subflow_seq, subflow->map_data_len); }static bool skb_is_fully_mapped (struct sock *ssk,struct sk_buff *skb)
@@ -782,13 +782,13 @@ static bool validate_mapping(struct sock *ssk, struct sk_buff *skb)/* Mapping covers data later in the subflow stream, * currently unsupported. */ -warn_bad_map (subflow, ssn); +dbg_bad_map (subflow, ssn);return false; }if (unlikely (!before (ssn, subflow->map_subflow_seq + subflow->map_data_len))) {/* Mapping does covers past subflow data, invalid */ -warn_bad_map (subflow, ssn + skb->len); +dbg_bad_map (subflow, ssn);return false; }return true;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 47/178 selftests: mptcp: enable syncookie only in absence of reorders
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 2395da0e17935ce9158cdfae433962bdb6cbfa67 ]
Syncookie validation may fail for OoO packets, causing spurious resets and self-tests failures, so let's force syncookie only for tests iteration with no OoO.
--- tools/testing/selftests/net/mptcp/mptcp_connect.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
tools/testing/selftests/net/mptcp/mptcp_connect.sh +8 -3
@@ -197,9 +197,6 @@ ip -net "$ns4" link set ns4eth3 up ip -net "$ns4" route add default via 10.0.3.2 ip -net "$ns4" route add default via dead:beef:3::2 -# use TCP syn cookies, even if no flooding was detected. -ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2 - set_ethtool_flags() { local ns="$1" local dev="$2"
@@ -711,6 +708,14 @@ for sender in $ns1 $ns2 $ns3 $ns4;do exit $ret fi + # ns1<->ns2 is not subject to reordering/tc delays. Use it to test + # mptcp syncookie support. + if [ $sender = $ns1 ]; then + ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=2 + else + ip netns exec "$ns2" sysctl -q net.ipv4.tcp_syncookies=1 + fi + run_tests "$ns2" $sender 10.0.1.2 run_tests "$ns2" $sender dead:beef:1::2 run_tests "$ns2" $sender 10.0.2.1
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 48/178 mptcp: fix soft lookup in subflow_error_report()
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 499ada5073361c631f2a3c4a8aed44d53b6f82ec ]
Maxim reported a soft lookup in subflow_error_report():
watchdog: BUG: soft lockup - CPU#0 stuck for 22s! [swapper/0:0] RIP: 0010:native_queued_spin_lock_slowpath RSP: 0018:ffffa859c0003bc0 EFLAGS: 00000202 RAX: 0000000000000101 RBX: 0000000000000001 RCX: 0000000000000000 RDX: ffff9195c2772d88 RSI: 0000000000000000 RDI: ffff9195c2772d88 RBP: ffff9195c2772d00 R08: 00000000000067b0 R09: c6e31da9eb1e44f4 R10: ffff9195ef379700 R11: ffff9195edb50710 R12: ffff9195c2772d88 R13: ffff9195f500e3d0 R14: ffff9195ef379700 R15: ffff9195ef379700 FS: 0000000000000000(0000) GS:ffff91961f400000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000c000407000 CR3: 0000000002988000 CR4: 00000000000006f0 Call Trace: <IRQ> _raw_spin_lock_bh subflow_error_report mptcp_subflow_data_available __mptcp_move_skbs_from_subflow mptcp_data_ready tcp_data_queue tcp_rcv_established tcp_v4_do_rcv tcp_v4_rcv ip_protocol_deliver_rcu ip_local_deliver_finish __netif_receive_skb_one_core netif_receive_skb rtl8139_poll 8139too __napi_poll net_rx_action __do_softirq __irq_exit_rcu common_interrupt </IRQ>
The calling function - mptcp_subflow_data_available() - can be invoked from different contexts:
- plain ssk socket lock
- ssk socket lock + mptcp_data_lock
- ssk socket lock + mptcp_data_lock + msk socket lock.
Since subflow_error_report() tries to acquire the mptcp_data_lock, the latter two call chains will cause soft lookup.
This change addresses the issue moving the error reporting call to outer functions, where the held locks list is known and the we can acquire only the needed one.
--- net/mptcp/protocol.c | 9 ++++++ net/mptcp/subflow.c | 75 +++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 36 deletions(-)
net/mptcp/protocol.c +9 -0
@@ -699,6 +699,12 @@ static bool move_skbs_to_msk(struct mptcp_sock *msk, struct sock *ssk)__mptcp_move_skbs_from_subflow (msk, ssk, &moved);__mptcp_ofo_queue (msk); +if (unlikely (ssk->sk_err)) { +if (!sock_owned_by_user (sk)) +__mptcp_error_report (sk); +else +set_bit (MPTCP_ERROR_REPORT , &msk->flags); + }/* If the moves have caught up with the DATA_FIN sequence number * it's time to ack the DATA_FIN and change socket state, but
@@ -1932,6 +1938,9 @@ static bool __mptcp_move_skbs(struct mptcp_sock *msk) done =__mptcp_move_skbs_from_subflow (msk, ssk, &moved);mptcp_data_unlock (sk);tcp_cleanup_rbuf (ssk, moved); + +if (unlikely (ssk->sk_err)) +__mptcp_error_report (sk);unlock_sock_fast (ssk, slowpath); }while (!done);
net/mptcp/subflow.c +39 -36
99 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 49/178 alx: Fix an error handling path in alx_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 33e381448cf7a05d76ac0b47d4a6531ecd0e5c53 ]
If an error occurs after a 'pci_enable_pcie_error_reporting()' call, it must be undone by a corresponding 'pci_disable_pcie_error_reporting()' call, as already done in the remove function.
--- drivers/net/ethernet/atheros/alx/main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/atheros/alx/main.c +1 -0
@@ -1849,6 +1849,7 @@ out_free_netdev:free_netdev (netdev); out_pci_release:pci_release_mem_regions (pdev); +pci_disable_pcie_error_reporting (pdev); out_pci_disable:pci_disable_device (pdev);return err;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 50/178 cxgb4: fix endianness when flashing boot image
In reply to Greg Kroah-HartmanFrom: Rahul Lakkireddy <[email protected]>
[ Upstream commit 42a2039753a7f758ba5c85cb199fcf10dc2111eb ]
Boot images are copied to memory and updated with current underlying device ID before flashing them to adapter. Ensure the updated images are always flashed in Big Endian to allow the firmware to read the new images during boot properly.
--- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 44 +++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-)
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +27 -17
@@ -3060,16 +3060,19 @@ int t4_read_flash(struct adapter *adapter, unsigned int addr,* @addr: the start address to write * @n: length of data to write in bytes * @data: the data to write +* @byte_oriented: whether to store data as bytes or as words * * Writes up to a page of data (256 bytes) to the serial flash starting * at the given address. All the data must be written to the same page. +* If @byte_oriented is set the write data is stored as byte stream +* (i.e. matches what on disk), otherwise in big-endian. */ static int t4_write_flash (struct adapter *adapter,unsigned int addr, -unsigned int n,const u8 *data) +unsigned int n,const u8 *data,bool byte_oriented) { -int ret; -u32 buf[64 ];unsigned int i, c, left, val, offset = addr &0xff ; +u32 buf[64 ]; +int ret;if (addr >= adapter->params.sf_size || offset + n >SF_PAGE_SIZE )return -EINVAL ;
@@ -3080,10 +3083,14 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr, (ret = sf1_write(adapter, 4, 1, 1, val)) != 0) goto unlock; -for (left = n; left; left -= c) { +for (left = n; left; left -= c, data += c) { c =min (left,4U ); -for (val =0 , i =0 ; i < c; ++i) - val = (val <<8 ) + *data++; +for (val =0 , i =0 ; i < c; ++i) { +if (byte_oriented) + val = (val <<8 ) + data[i]; +else + val = (val <<8 ) + data[c - i -1 ]; + } ret =sf1_write (adapter, c, c != left,1 , val);if (ret)
@@ -3096,7 +3103,8 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr,t4_write_reg (adapter,SF_OP_A ,0 );/* unlock SF */ /* Read the page to verify the write succeeded */ - ret =t4_read_flash (adapter, addr & ~0xff ,ARRAY_SIZE (buf), buf,1 ); + ret =t4_read_flash (adapter, addr & ~0xff ,ARRAY_SIZE (buf), buf, + byte_oriented);if (ret)return ret;
@@ -3692,7 +3700,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)*/ memcpy (first_page, fw_data,SF_PAGE_SIZE ); ((struct fw_hdr *)first_page)->fw_ver =cpu_to_be32 (0xffffffff ); - ret =t4_write_flash (adap, fw_start,SF_PAGE_SIZE , first_page); + ret =t4_write_flash (adap, fw_start,SF_PAGE_SIZE , first_page, true);if (ret) goto out;
@@ -3700,14 +3708,14 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)for (size -=SF_PAGE_SIZE ; size; size -=SF_PAGE_SIZE ) { addr +=SF_PAGE_SIZE ; fw_data +=SF_PAGE_SIZE ; - ret =t4_write_flash (adap, addr,SF_PAGE_SIZE , fw_data); + ret =t4_write_flash (adap, addr,SF_PAGE_SIZE , fw_data, true);if (ret) goto out; } - ret =t4_write_flash (adap, - fw_start + offsetof(struct fw_hdr , fw_ver), -sizeof (hdr->fw_ver), (const u8 *)&hdr->fw_ver); + ret =t4_write_flash (adap, fw_start + offsetof(struct fw_hdr , fw_ver), +sizeof (hdr->fw_ver), (const u8 *)&hdr->fw_ver, + true); out:if (ret) dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
@@ -10208,7 +10216,7 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) n = size - i; else n =SF_PAGE_SIZE ; - ret =t4_write_flash (adap, addr, n, cfg_data); + ret =t4_write_flash (adap, addr, n, cfg_data, true);if (ret) goto out;
@@ -10677,13 +10685,14 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data,for (size -=SF_PAGE_SIZE ; size; size -=SF_PAGE_SIZE ) { addr +=SF_PAGE_SIZE ; boot_data +=SF_PAGE_SIZE ; - ret =t4_write_flash (adap, addr,SF_PAGE_SIZE , boot_data); + ret =t4_write_flash (adap, addr,SF_PAGE_SIZE , boot_data, + false);if (ret) goto out; } ret =t4_write_flash (adap, boot_sector,SF_PAGE_SIZE , - (const u8 *)header); + (const u8 *)header, false); out:if (ret)
@@ -10758,7 +10767,7 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)for (i =0 ; i < size; i +=SF_PAGE_SIZE ) { n =min_t (u32, size - i,SF_PAGE_SIZE ); - ret =t4_write_flash (adap, addr, n, cfg_data); + ret =t4_write_flash (adap, addr, n, cfg_data, false);if (ret) goto out;
@@ -10770,7 +10779,8 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)for (i =0 ; i < npad; i++) {u8 data =0 ; - ret =t4_write_flash (adap, cfg_addr + size + i,1 , &data); + ret =t4_write_flash (adap, cfg_addr + size + i,1 , &data, + false);if (ret) goto out; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 51/178 cxgb4: fix sleep in atomic when flashing PHY firmware
In reply to Greg Kroah-HartmanFrom: Rahul Lakkireddy <[email protected]>
[ Upstream commit f046bd0ae15d8a0bbe57d4647da182420f720c3d ]
Before writing new PHY firmware to on-chip memory, driver queries firmware for current running PHY firmware version, which can result in sleep waiting for reply. So, move spinlock closer to the actual on-chip memory write operation, instead of taking it at the callers.
--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 2 -- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 2 -- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 ++ 3 files changed, 2 insertions(+), 4 deletions(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +0 -2
@@ -1337,9 +1337,7 @@ static int cxgb4_ethtool_flash_phy(struct net_device *netdev,return ret; } -spin_lock_bh (&adap->win0_lock); ret =t4_load_phy_fw (adap,MEMWIN_NIC ,NULL , data, size); -spin_unlock_bh (&adap->win0_lock);if (ret)dev_err (adap->pdev_dev,"Failed to load PHY FW\n" );
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +0 -2
@@ -4424,10 +4424,8 @@ static int adap_init0_phy(struct adapter *adap)/* Load PHY Firmware onto adapter. */ -spin_lock_bh (&adap->win0_lock); ret =t4_load_phy_fw (adap,MEMWIN_NIC , phy_info->phy_fw_version, (u8 *)phyf->data, phyf->size); -spin_unlock_bh (&adap->win0_lock);if (ret <0 )dev_err (adap->pdev_dev,"PHY Firmware transfer error %d\n" , -ret);
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +2 -0
@@ -3820,9 +3820,11 @@ int t4_load_phy_fw(struct adapter *adap, int win,/* Copy the supplied PHY Firmware image to the adapter memory location * allocated by the adapter firmware. */ +spin_lock_bh (&adap->win0_lock); ret =t4_memory_rw (adap, win, mtype, maddr, phy_fw_size, (__be32 *)phy_fw_data,T4_MEMORY_WRITE ); +spin_unlock_bh (&adap->win0_lock);if (ret)return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 52/178 cxgb4: halt chip before flashing PHY firmware image
In reply to Greg Kroah-HartmanFrom: Rahul Lakkireddy <[email protected]>
[ Upstream commit 6d297540f75d759489054e8b07932208fc4db2cb ]
When using firmware-assisted PHY firmware image write to flash, halt the chip before beginning the flash write operation to allow the running firmware to store the image persistently. Otherwise, the running firmware will only store the PHY image in local on-chip RAM, which will be lost after next reset.
--- .../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +19 -3
@@ -1337,11 +1337,27 @@ static int cxgb4_ethtool_flash_phy(struct net_device *netdev,return ret; } +/* We have to RESET the chip/firmware because we need the +* chip in uninitialized state for loading new PHY image. +* Otherwise, the running firmware will only store the PHY +* image in local RAM which will be lost after next reset. +*/ + ret =t4_fw_reset (adap, adap->mbox,PIORSTMODE_F |PIORST_F ); +if (ret <0 ) { +dev_err (adap->pdev_dev, +"Set FW to RESET for flashing PHY FW failed. ret: %d\n" , + ret); +return ret; + } + ret =t4_load_phy_fw (adap,MEMWIN_NIC ,NULL , data, size); -if (ret) -dev_err (adap->pdev_dev,"Failed to load PHY FW\n" ); +if (ret <0 ) { +dev_err (adap->pdev_dev,"Failed to load PHY FW. ret: %d\n" , + ret); +return ret; + } -return ret; +return 0 ; } static int cxgb4_ethtool_flash_fw(struct net_device *netdev,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 53/178 net: stmmac: dwmac1000: Fix extended MAC address registers definition
In reply to Greg Kroah-HartmanFrom: Jisheng Zhang <[email protected]>
[ Upstream commit 1adb20f0d496b2c61e9aa1f4761b8d71f93d258e ]
The register starts from 0x800 is the 16th MAC address register rather than the first one.
--- drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +4 -4
@@ -76,10 +76,10 @@ enum power_event {#define LPI_CTRL_STATUS_TLPIEN 0x00000001/* Transmit LPI Entry */ /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH (reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ - (reg * 8)) -#define GMAC_ADDR_LOW (reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ - (reg * 8)) +#define GMAC_ADDR_HIGH (reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \ + 0x00000040 + (reg * 8)) +#define GMAC_ADDR_LOW (reg) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 : \ + 0x00000044 + (reg * 8))#define GMAC_MAX_PERFECT_ADDRESSES 1#define GMAC_PCS_BASE 0x000000c0/* PCS register base */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 54/178 net: make get_net_ns return error if NET_NS is disabled
In reply to Greg Kroah-HartmanFrom: Changbin Du <[email protected]>
[ Upstream commit ea6932d70e223e02fea3ae20a4feff05d7c1ea9a ]
There is a panic in socket ioctl cmd SIOCGSKNS when NET_NS is not enabled. The reason is that nsfs tries to access ns->ops but the proc_ns_operations is not implemented in this case.
[7.670023] Unable to handle kernel NULL pointer dereference at virtual address 00000010 [7.670268] pgd = 32b54000 [7.670544] [00000010] *pgd=00000000 [7.671861] Internal error: Oops: 5 [#1] SMP ARM [7.672315] Modules linked in: [7.672918] CPU: 0 PID: 1 Comm: systemd Not tainted 5.13.0-rc3-00375-g6799d4f2da49 #16 [7.673309] Hardware name: Generic DT based system [7.673642] PC is at nsfs_evict+0x24/0x30 [7.674486] LR is at clear_inode+0x20/0x9c
The same to tun SIOCGSKNS command.
To fix this problem, we make get_net_ns() return -EINVAL when NET_NS is disabled. Meanwhile move it to right place net/core/net_namespace.c.
--- include/linux/socket.h | 2 -- include/net/net_namespace.h | 7 +++++++ net/core/net_namespace.c | 12 ++++++++++++ net/socket.c | 13 ------------- 4 files changed, 19 insertions(+), 15 deletions(-)
include/linux/socket.h +0 -2
@@ -438,6 +438,4 @@ extern int __sys_socketpair(int family, int type, int protocol, int __user *usockvec);extern int __sys_shutdown_sock (struct socket *sock,int how);extern int __sys_shutdown (int fd,int how); - -extern struct ns_common *get_net_ns (struct ns_common *ns);#endif /* _LINUX_SOCKET_H */
include/net/net_namespace.h +7 -0
@@ -197,6 +197,8 @@ struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns,void net_ns_get_ownership (const struct net *net,kuid_t *uid,kgid_t *gid);void net_ns_barrier (void ); + +struct ns_common *get_net_ns (struct ns_common *ns);#else /* CONFIG_NET_NS */ #include <linux/sched.h> #include <linux/nsproxy.h>
@@ -216,6 +218,11 @@ static inline void net_ns_get_ownership(const struct net *net, }static inline void net_ns_barrier (void ) {} + +static inline struct ns_common *get_net_ns (struct ns_common *ns) +{ +return ERR_PTR (-EINVAL ); +}#endif /* CONFIG_NET_NS */
net/core/net_namespace.c +12 -0
@@ -641,6 +641,18 @@ void __put_net(struct net *net) }EXPORT_SYMBOL_GPL (__put_net); +/** +* get_net_ns - increment the refcount of the network namespace +* @ns: common namespace (net) +* +* Returns the net's common namespace. +*/ +struct ns_common *get_net_ns (struct ns_common *ns) +{ + return &get_net(container_of(ns, struct net, ns))->ns; +} +EXPORT_SYMBOL_GPL (get_net_ns); +struct net *get_net_ns_by_fd (int fd) {struct file *file;
net/socket.c +0 -13
@@ -1072,19 +1072,6 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,* what to do with it - that's up to the protocol still. */ -/** -* get_net_ns - increment the refcount of the network namespace -* @ns: common namespace (net) -* -* Returns the net's common namespace. -*/ - -struct ns_common *get_net_ns (struct ns_common *ns) -{ - return &get_net(container_of(ns, struct net, ns))->ns; -} -EXPORT_SYMBOL_GPL (get_net_ns); -static long sock_ioctl (struct file *file,unsigned cmd,unsigned long arg) {struct socket *sock;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 55/178 net: qualcomm: rmnet: dont over-count statistics
In reply to Greg Kroah-HartmanFrom: Alex Elder <[email protected]>
[ Upstream commit 994c393bb6886d6d94d628475b274a8cb3fc67a4 ]
The purpose of the loop using u64_stats_fetch_*_irq() is to ensure statistics on a given CPU are collected atomically. If one of the statistics values gets updated within the begin/retry window, the loop will run again.
Currently the statistics totals are updated inside that window. This means that if the loop ever retries, the statistics for the CPU will be counted more than once.
Fix this by taking a snapshot of a CPU's statistics inside the protected window, and then updating the counters with the snapshot values after exiting the loop.
(Also add a newline at the end of this file...)
--- .../net/ethernet/qualcomm/rmnet/rmnet_vnd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +9 -9
@@ -126,24 +126,24 @@ static void rmnet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *s) {struct rmnet_priv *priv =netdev_priv (dev); -struct rmnet_vnd_stats total_stats; +struct rmnet_vnd_stats total_stats = { };struct rmnet_pcpu_stats *pcpu_ptr; +struct rmnet_vnd_stats snapshot;unsigned int cpu, start; -memset (&total_stats,0 ,sizeof (struct rmnet_vnd_stats )); -for_each_possible_cpu (cpu) { pcpu_ptr =per_cpu_ptr (priv->pcpu_stats, cpu);do { start =u64_stats_fetch_begin_irq (&pcpu_ptr->syncp); - total_stats.rx_pkts += pcpu_ptr->stats.rx_pkts; - total_stats.rx_bytes += pcpu_ptr->stats.rx_bytes; - total_stats.tx_pkts += pcpu_ptr->stats.tx_pkts; - total_stats.tx_bytes += pcpu_ptr->stats.tx_bytes; + snapshot = pcpu_ptr->stats;/* struct assignment */ }while (u64_stats_fetch_retry_irq (&pcpu_ptr->syncp, start)); - total_stats.tx_drops += pcpu_ptr->stats.tx_drops; + total_stats.rx_pkts += snapshot.rx_pkts; + total_stats.rx_bytes += snapshot.rx_bytes; + total_stats.tx_pkts += snapshot.tx_pkts; + total_stats.tx_bytes += snapshot.tx_bytes; + total_stats.tx_drops += snapshot.tx_drops; } s->rx_packets = total_stats.rx_pkts;
@@ -354,4 +354,4 @@ int rmnet_vnd_update_dev_mtu(struct rmnet_port *port, }return 0 ; -} +}
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 56/178 ethtool: strset: fix message length calculation
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit e175aef902697826d344ce3a12189329848fe898 ]
Outer nest for ETHTOOL_A_STRSET_STRINGSETS is not accounted for. This may result in ETHTOOL_MSG_STRSET_GET producing a warning like:
calculated message payload length (684) not sufficient
WARNING: CPU: 0 PID: 30967 at net/ethtool/netlink.c:369 ethnl_default_doit+0x87a/0xa20
and a splat.
As usually with such warnings three conditions must be met for the warning to trigger:
- there must be no skb size rounding up (e.g. reply_size of 684);
- string set must be per-device (so that the header gets populated);
- the device name must be at least 12 characters long.
all in all with current user space it looks like reading priv flags is the only place this could potentially happen. Or with syzbot :)
--- net/ethtool/strset.c | 2 ++ 1 file changed, 2 insertions(+)
net/ethtool/strset.c +2 -0
@@ -328,6 +328,8 @@ static int strset_reply_size(const struct ethnl_req_info *req_base,int len =0 ;int ret; + len +=nla_total_size (0 );/* ETHTOOL_A_STRSET_STRINGSETS */ +for (i =0 ; i <ETH_SS_COUNT ; i++) {const struct strset_info *set_info = &data->sets[i];
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 57/178 qlcnic: Fix an error handling path in qlcnic_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit cb3376604a676e0302258b01893911bdd7aa5278 ]
If an error occurs after a 'pci_enable_pcie_error_reporting()' call, it must be undone by a corresponding 'pci_disable_pcie_error_reporting()' call, as already done in the remove function.
--- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +1 -0
@@ -2690,6 +2690,7 @@ err_out_free_hw_res:kfree (ahw); err_out_free_res: +pci_disable_pcie_error_reporting (pdev);pci_release_regions (pdev); err_out_disable_pdev:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 58/178 netxen_nic: Fix an error handling path in netxen_nic_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 49a10c7b176295f8fafb338911cf028e97f65f4d ]
If an error occurs after a 'pci_enable_pcie_error_reporting()' call, it must be undone by a corresponding 'pci_disable_pcie_error_reporting()' call, as already done in the remove function.
--- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +2 -0
@@ -1602,6 +1602,8 @@ err_out_free_netdev:free_netdev (netdev); err_out_free_res: +if (NX_IS_REVISION_P3 (pdev->revision)) +pci_disable_pcie_error_reporting (pdev);pci_release_regions (pdev); err_out_disable_pdev:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 59/178 cxgb4: fix wrong ethtool n-tuple rule lookup
In reply to Greg Kroah-HartmanFrom: Rahul Lakkireddy <[email protected]>
[ Upstream commit 09427c1915f754ebe7d3d8e54e79bbee48afe916 ]
The TID returned during successful filter creation is relative to the region in which the filter is created. Using it directly always returns Hi Prio/Normal filter region's entry for the first couple of entries, even though the rule is actually inserted in Hash region. Fix by analyzing in which region the filter has been inserted and save the absolute TID to be used for lookup later.
--- .../ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +16 -8
@@ -1624,16 +1624,14 @@ static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap, u32 ftid) {struct tid_info *t = &adap->tids; -struct filter_entry *f; -if (ftid < t->nhpftids) - f = &adap->tids.hpftid_tab[ftid]; -else if (ftid < t->nftids) - f = &adap->tids.ftid_tab[ftid - t->nhpftids]; -else - f =lookup_tid (&adap->tids, ftid); +if (ftid >= t->hpftid_base && ftid < t->hpftid_base + t->nhpftids) +return &t->hpftid_tab[ftid - t->hpftid_base]; + +if (ftid >= t->ftid_base && ftid < t->ftid_base + t->nftids) +return &t->ftid_tab[ftid - t->ftid_base]; -return f; +return lookup_tid (t, ftid); } static void cxgb4_fill_filter_rule(struct ethtool_rx_flow_spec *fs,
@@ -1840,6 +1838,11 @@ static int cxgb4_ntuple_del_filter(struct net_device *dev, filter_id = filter_info->loc_array[cmd->fs.location]; f =cxgb4_get_filter_entry (adapter, filter_id); +if (f->fs.prio) + filter_id -= adapter->tids.hpftid_base; +else if (!f->fs.hash) + filter_id -= (adapter->tids.ftid_base - adapter->tids.nhpftids); + ret =cxgb4_flow_rule_destroy (dev, f->fs.tc_prio, &f->fs, filter_id);if (ret) goto err;
@@ -1899,6 +1902,11 @@ static int cxgb4_ntuple_set_filter(struct net_device *netdev, filter_info = &adapter->ethtool_filters->port[pi->port_id]; +if (fs.prio) + tid += adapter->tids.hpftid_base; +else if (!fs.hash) + tid += (adapter->tids.ftid_base - adapter->tids.nhpftids); + filter_info->loc_array[cmd->fs.location] = tid;set_bit (cmd->fs.location, filter_info->bmap); filter_info->in_use++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 60/178 ipv4: Fix device used for dst_alloc with local routes
In reply to Greg Kroah-HartmanFrom: David Ahern <[email protected]>
[ Upstream commit b87b04f5019e821c8c6c7761f258402e43500a1f ]
Oliver reported a use case where deleting a VRF device can hang waiting for the refcnt to drop to 0. The root cause is that the dst is allocated against the VRF device but cached on the loopback device.
The use case (added to the selftests) has an implicit VRF crossing due to the ordering of the FIB rules (lookup local is before the l3mdev rule, but the problem occurs even if the FIB rules are re-ordered with local after l3mdev because the VRF table does not have a default route to terminate the lookup). The end result is is that the FIB lookup returns the loopback device as the nexthop, but the ingress device is in a VRF. The mismatch causes the dst alloc against the VRF device but then cached on the loopback.
The fix is to bring the trick used for IPv6 (see ip6_rt_get_dev_rcu):
pick the dst alloc device based the fib lookup result but with checks that the result has a nexthop device (e.g., not an unreachable or prohibit entry).
--- net/ipv4/route.c | 15 +++++++++++++- tools/testing/selftests/net/fib_tests.sh | 25 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-)
net/ipv4/route.c +14 -1
@@ -2081,6 +2081,19 @@ martian_source:return err; } +/* get device for dst_alloc with local routes */ +static struct net_device *ip_rt_get_dev (struct net *net, +const struct fib_result *res) +{ +struct fib_nh_common *nhc = res->fi ? res->nhc :NULL ; +struct net_device *dev =NULL ; + +if (nhc) + dev =l3mdev_master_dev_rcu (nhc->nhc_dev); + +return dev ? : net->loopback_dev; +} +/* * NOTE. We drop all the packets that has local source * addresses, because every properly looped back packet
@@ -2237,7 +2250,7 @@ local_input: } } - rth =rt_dst_alloc (l3mdev_master_dev_rcu (dev) ? : net->loopback_dev, + rth =rt_dst_alloc (ip_rt_get_dev (net, res), flags |RTCF_LOCAL , res->type,IN_DEV_ORCONF (in_dev,NOPOLICY ), false);if (!rth)
tools/testing/selftests/net/fib_tests.sh +25 -0
@@ -1384,12 +1384,37 @@ ipv4_rt_replace() ipv4_rt_replace_mpath } +# checks that cached input route on VRF port is deleted +# when VRF is deleted +ipv4_local_rt_cache() +{ + run_cmd "ip addr add 10.0.0.1/32 dev lo" + run_cmd "ip netns add test-ns" + run_cmd "ip link add veth-outside type veth peer name veth-inside" + run_cmd "ip link add vrf-100 type vrf table 1100" + run_cmd "ip link set veth-outside master vrf-100" + run_cmd "ip link set veth-inside netns test-ns" + run_cmd "ip link set veth-outside up" + run_cmd "ip link set vrf-100 up" + run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100" + run_cmd "ip netns exec test-ns ip link set veth-inside up" + run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside" + run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside" + run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1" + run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1" + run_cmd "ip link delete vrf-100" + + # if we do not hang test is a success + log_test $? 0 "Cached route removed from VRF port device" +} + ipv4_route_test() { route_setup ipv4_rt_add ipv4_rt_replace + ipv4_local_rt_cache route_cleanup }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 61/178 net: qrtr: fix OOB Read in qrtr_endpoint_post
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit ad9d24c9429e2159d1e279dc3a83191ccb4daf1d ]
Syzbot reported slab-out-of-bounds Read inqrtr_endpoint_post. The problem was in wrong
_size_ type:
if (len != ALIGN(size, 4) + hdrlen) goto err;
If size from qrtr_hdr is 4294967293 (0xfffffffd), the result of ALIGN(size, 4) will be 0. In case of len == hdrlen and size == 4294967293 in header this check won't fail and
skb_put_data(skb, data + hdrlen, size);
will read out of bound from data, which is hdrlen allocated block.
--- net/qrtr/qrtr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/qrtr/qrtr.c +1 -1
@@ -435,7 +435,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)struct qrtr_sock *ipc;struct sk_buff *skb;struct qrtr_cb *cb; -unsigned int size; +size_t size;unsigned int ver;size_t hdrlen;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 62/178 bpf: Fix leakage under speculation on mispredicted branches
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
[ Upstream commit 9183671af6dbf60a1219371d4ed73e23f43b49db ]
The verifier only enumerates valid control-flow paths and skips paths that are unreachable in the non-speculative domain. And so it can miss issues under speculative execution on mispredicted branches.
For example, a type confusion has been demonstrated with the following crafted program:
// r0 = pointer to a map array entry
// r6 = pointer to readable stack slot
// r9 = scalar controlled by attacker
1: r0 = *(u64 *)(r0) // cache miss
2: if r0 != 0x0 goto line 4
3: r6 = r9
4: if r0 != 0x1 goto line 6
5: r9 = *(u8 *)(r6)
6: // leak r9
Since line 3 runs iff r0 == 0 and line 5 runs iff r0 == 1, the verifier concludes that the pointer dereference on line 5 is safe. But: if the attacker trains both the branches to fall-through, such that the following is speculatively executed ...
r6 = r9
r9 = *(u8 *)(r6)
// leak r9
... then the program will dereference an attacker-controlled value and could leak its content under speculative execution via side-channel. This requires to mistrain the branch predictor, which can be rather tricky, because the branches are mutually exclusive. However such training can be done at congruent addresses in user space using different branches that are not mutually exclusive. That is, by training branches in user space ...
A: if r0 != 0x0 goto line C B: ... C: if r0 != 0x0 goto line D D: ...
... such that addresses A and C collide to the same CPU branch prediction entries in the PHT (pattern history table) as those of the BPF program's lines 2 and 4, respectively. A non-privileged attacker could simply brute force such collisions in the PHT until observing the attack succeeding.
Alternative methods to mistrain the branch predictor are also possible that avoid brute forcing the collisions in the PHT. A reliable attack has been demonstrated, for example, using the following crafted program:
// r0 = pointer to a [control] map array entry
// r7 = *(u64 *)(r0 + 0), training/attack phase
// r8 = *(u64 *)(r0 + 8), oob address
// [...]
// r0 = pointer to a [data] map array entry
1: if r7 == 0x3 goto line 3
2: r8 = r0
// crafted sequence of conditional jumps to separate the conditional // branch in line 193 from the current execution flow
3: if r0 != 0x0 goto line 5
4: if r0 == 0x0 goto exit
5: if r0 != 0x0 goto line 7
6: if r0 == 0x0 goto exit
[...]
187: if r0 != 0x0 goto line 189
188: if r0 == 0x0 goto exit
// load any slowly-loaded value (due to cache miss in phase 3) ... 189: r3 = *(u64 *)(r0 + 0x1200)
// ... and turn it into known zero for verifier, while preserving slowly- // loaded dependency when executing:
190: r3 &= 1
191: r3 &= 2
// speculatively bypassed phase dependency
192: r7 += r3
193: if r7 == 0x3 goto exit
194: r4 = *(u8 *)(r8 + 0)
// leak r4
As can be seen, in training phase (phase != 0x3), the condition in line 1 turns into false and therefore r8 with the oob address is overridden with the valid map value address, which in line 194 we can read out without issues. However, in attack phase, line 2 is skipped, and due to the cache miss in line 189 where the map value is (zeroed and later) added to the phase register, the condition in line 193 takes the fall-through path due to prior branch predictor training, where under speculation, it'll load the byte at oob address r8 (unknown scalar type at that point) which could then be leaked via side-channel.
One way to mitigate these is to 'branch off' an unreachable path, meaning, the current verification path keeps following the is_branch_taken() path and we push the other branch to the verification stack. Given this is unreachable from the non-speculative domain, this branch's vstate is explicitly marked as speculative. This is needed for two reasons: i) if this path is solely seen from speculative execution, then we later on still want the dead code elimination to kick in in order to sanitize these instructions with jmp-1s, and ii) to ensure that paths walked in the non-speculative domain are not pruned from earlier walks of paths walked in the speculative domain. Additionally, for robustness, we mark the registers which have been part of the conditional as unknown in the speculative path given there should be no assumptions made on their content.
The fix in here mitigates type confusion attacks described earlier due to
i) all code paths in the BPF program being explored and ii) existing verifier logic already ensuring that given memory access instruction references one specific data structure.
An alternative to this fix that has also been looked at in this scope was to mark aux->alu_state at the jump instruction with a BPF_JMP_TAKEN state as well as direction encoding (always-goto, always-fallthrough, unknown), such that mixing of different always-* directions themselves as well as mixing of always-* with unknown directions would cause a program rejection by the verifier, e.g. programs with constructs like 'if ([...]) { x = 0; } else { x = 1; }' with subsequent 'if (x == 1) { [...] }'. For unprivileged, this would result in only single direction always-* taken paths, and unknown taken paths being allowed, such that the former could be patched from a conditional jump to an unconditional jump (ja). Compared to this approach here, it would have two downsides: i) valid programs that otherwise are not performing any pointer arithmetic, etc, would potentially be rejected/broken, and ii) we are required to turn off path pruning for unprivileged, where both can be avoided in this work through pushing the invalid branch to the verification stack.
The issue was originally discovered by Adam and Ofek, and later independently discovered and reported as a result of Benedict and Piotr's research work.
--- kernel/bpf/verifier.c | 44 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-)
kernel/bpf/verifier.c +40 -4
@@ -5937,6 +5937,27 @@ struct bpf_sanitize_info {bool mask_to_left; }; +static struct bpf_verifier_state * +sanitize_speculative_path (struct bpf_verifier_env *env, +const struct bpf_insn *insn, +u32 next_idx,u32 curr_idx) +{ +struct bpf_verifier_state *branch; +struct bpf_reg_state *regs; + + branch =push_stack (env, next_idx, curr_idx, true); +if (branch && insn) { + regs = branch->frame[branch->curframe]->regs; +if (BPF_SRC (insn->code) ==BPF_K ) { +mark_reg_unknown (env, regs, insn->dst_reg); + }else if (BPF_SRC (insn->code) ==BPF_X ) { +mark_reg_unknown (env, regs, insn->dst_reg); +mark_reg_unknown (env, regs, insn->src_reg); + } + } +return branch; +} + static int sanitize_ptr_alu(struct bpf_verifier_env *env, struct bpf_insn *insn, const struct bpf_reg_state *ptr_reg,
@@ -6020,7 +6041,8 @@ do_sim: tmp = *dst_reg; *dst_reg = *ptr_reg; } - ret =push_stack (env, env->insn_idx +1 , env->insn_idx, true); + ret =sanitize_speculative_path (env,NULL , env->insn_idx +1 , + env->insn_idx);if (!ptr_is_dst_reg && ret) *dst_reg = tmp;return !ret ?REASON_STACK :0 ;
@@ -8204,14 +8226,28 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,if (err)return err; } +if (pred ==1 ) { -/* only follow the goto, ignore fall-through */ +/* Only follow the goto, ignore fall-through. If needed, push +* the fall-through branch for simulation under speculative +* execution. +*/ +if (!env->bypass_spec_v1 && + !sanitize_speculative_path (env, insn, *insn_idx +1 , + *insn_idx)) +return -EFAULT ; *insn_idx += insn->off;return 0 ; }else if (pred ==0 ) { -/* only follow fall-through branch, since -* that's where the program will go +/* Only follow the fall-through branch, since that's where the +* program will go. If needed, push the goto branch for +* simulation under speculative execution. */ +if (!env->bypass_spec_v1 && + !sanitize_speculative_path (env, insn, + *insn_idx + insn->off +1 , + *insn_idx)) +return -EFAULT ;return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 63/178 net: mhi_net: Update the transmit handler prototype
In reply to Greg Kroah-HartmanFrom: Subash Abhinov Kasiviswanathan <[email protected]>
[ Upstream commit 2214fb53006e6cfa6371b706070cb99794c68c3b ]
Update the function prototype of mhi_ndo_xmit to match ndo_start_xmit. This otherwise leads to run time failures when CFI is enabled in kernel.
--- drivers/net/mhi/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/mhi/net.c +1 -1
@@ -49,7 +49,7 @@ static int mhi_ndo_stop(struct net_device *ndev)return 0 ; } -static int mhi_ndo_xmit (struct sk_buff *skb,struct net_device *ndev) +static netdev_tx_t mhi_ndo_xmit (struct sk_buff *skb,struct net_device *ndev) {struct mhi_net_dev *mhi_netdev =netdev_priv (ndev);const struct mhi_net_proto *proto = mhi_netdev->proto;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 64/178 ptp: improve max_adj check against unreasonable values
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
[ Upstream commit 475b92f932168a78da8109acd10bfb7578b8f2bb ]
Scaled PPM conversion to PPB may (on 64bit systems) result in a value larger than s32 can hold (freq/scaled_ppm is a long). This means the kernel will not correctly reject unreasonably high ->freq values (e.g. > 4294967295ppb, 281474976645 scaled PPM).
The conversion is equivalent to a division by ~66 (65.536), so the value of ppb is always smaller than ppm, but not small enough to assume narrowing the type from long -> s32 is okay.
Note that reasonable user space (e.g. ptp4l) will not use such high values, anyway, 4289046510ppb ~= 4.3x, so the fix is somewhat pedantic.
--- drivers/ptp/ptp_clock.c | 6 +++--- include/linux/ptp_clock_kernel.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/ptp/ptp_clock.c +3 -3
@@ -63,7 +63,7 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue,spin_unlock_irqrestore (&queue->lock, flags); } -s32 scaled_ppm_to_ppb (long ppm) +long scaled_ppm_to_ppb (long ppm) {/* * The 'freq' field in the 'struct timex' is in parts per
@@ -80,7 +80,7 @@ s32 scaled_ppm_to_ppb(long ppm)s64 ppb =1 + ppm; ppb *=125 ; ppb >>=13 ; -return (s32 ) ppb; +return (long ) ppb; }EXPORT_SYMBOL (scaled_ppm_to_ppb);
@@ -138,7 +138,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) delta =ktime_to_ns (kt); err = ops->adjtime (ops, delta); }else if (tx->modes &ADJ_FREQUENCY ) { -s32 ppb =scaled_ppm_to_ppb (tx->freq); +long ppb =scaled_ppm_to_ppb (tx->freq);if (ppb > ops->max_adj || ppb < -ops->max_adj)return -ERANGE ;if (ops->adjfine)
include/linux/ptp_clock_kernel.h +1 -1
@@ -235,7 +235,7 @@ extern int ptp_clock_index(struct ptp_clock *ptp);* @ppm: Parts per million, but with a 16 bit binary fractional field */ -extern s32 scaled_ppm_to_ppb (long ppm); +extern long scaled_ppm_to_ppb (long ppm);/** * ptp_find_pin() - obtain the pin index of a given auxiliary function
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 65/178 net: cdc_ncm: switch to eth%d interface naming
In reply to Greg Kroah-HartmanFrom: Maciej Żenczykowski <[email protected]>
[ Upstream commit c1a3d4067309451e68c33dbd356032549cc0bd8e ]
This is meant to make the host side cdc_ncm interface consistently named just like the older CDC protocols: cdc_ether & cdc_ecm (and even rndis_host), which all use 'FLAG_ETHER | FLAG_POINTTOPOINT'.
include/linux/usb/usbnet.h:
#define FLAG_ETHER 0x0020 /* maybe use "eth%d" names */
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
#define FLAG_WWAN 0x0400 /* use "wwan%d" names */
#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */
drivers/net/usb/usbnet.c @ line 1711:
strcpy (net->name, "usb%d");
...
// heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better.
if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
(net->dev_addr [0] & 0x02) == 0))
strcpy (net->name, "eth%d");
/* WLAN devices should always be named "wlan%d" */
if ((dev->driver_info->flags & FLAG_WLAN) != 0)
strcpy(net->name, "wlan%d");
/* WWAN devices should always be named "wwan%d" */
if ((dev->driver_info->flags & FLAG_WWAN) != 0)
strcpy(net->name, "wwan%d");So by using ETHER | POINTTOPOINT the interface naming is either usb%d or eth%d based on the global uniqueness of the mac address of the device.
Without this 2.5gbps ethernet dongles which all seem to use the cdc_ncm driver end up being called usb%d instead of eth%d even though they're definitely not two-host. (All 1gbps & 5gbps ethernet usb dongles I've tested don't hit this problem due to use of different drivers, primarily r8152 and aqc111)
Fixes tag is based purely on git blame, and is really just here to make sure this hits LTS branches newer than v4.5.
--- drivers/net/usb/cdc_ncm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/cdc_ncm.c +1 -1
@@ -1902,7 +1902,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)static const struct driver_info cdc_ncm_info = { .description ="CDC NCM" , .flags =FLAG_POINTTOPOINT |FLAG_NO_SETINT |FLAG_MULTI_PACKET - |FLAG_LINK_INTR , + |FLAG_LINK_INTR |FLAG_ETHER , .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 66/178 lantiq: net: fix duplicated skb in rx descriptor ring
In reply to Greg Kroah-HartmanFrom: Aleksander Jan Bajkowski <[email protected]>
[ Upstream commit 7ea6cd16f1599c1eac6018751eadbc5fc736b99a ]
The previous commit didn't fix the bug properly. By mistake, it replaces the pointer of the next skb in the descriptor ring instead of the current one. As a result, the two descriptors are assigned the same SKB. The error is seen during the iperf test when skb_put tries to insert a second packet and exceeds the available buffer.
--- drivers/net/ethernet/lantiq_xrx200.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/lantiq_xrx200.c +2 -1
@@ -154,6 +154,7 @@ static int xrx200_close(struct net_device *net_dev)static int xrx200_alloc_skb (struct xrx200_chan *ch) { +struct sk_buff *skb = ch->skb[ch->dma.desc];dma_addr_t mapping;int ret =0 ;
@@ -168,6 +169,7 @@ static int xrx200_alloc_skb(struct xrx200_chan *ch) XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);if (unlikely (dma_mapping_error (ch->priv->dev, mapping))) {dev_kfree_skb_any (ch->skb[ch->dma.desc]); + ch->skb[ch->dma.desc] = skb; ret = -ENOMEM ; goto skip; }
@@ -198,7 +200,6 @@ static int xrx200_hw_receive(struct xrx200_chan *ch) ch->dma.desc %=LTQ_DESC_NUM ;if (ret) { - ch->skb[ch->dma.desc] = skb; net_dev->stats.rx_dropped++;netdev_err (net_dev,"failed to allocate new rx buffer\n" );return ret;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 67/178 net: usb: fix possible use-after-free in smsc75xx_bind
In reply to Greg Kroah-HartmanFrom: Dongliang Mu <[email protected]>
[ Upstream commit 56b786d86694e079d8aad9b314e015cd4ac02a3d ]
The commit 46a8b29c6306 ("net: usb: fix memory leak in smsc75xx_bind") fails to clean up the work scheduled in smsc75xx_reset-> smsc75xx_set_multicast, which leads to use-after-free if the work is scheduled to start after the deallocation. In addition, this patch also removes a dangling pointer - dev->data[0].
This patch calls cancel_work_sync to cancel the scheduled work and set the dangling pointer to NULL.
--- drivers/net/usb/smsc75xx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/net/usb/smsc75xx.c +6 -4
@@ -1483,7 +1483,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret =smsc75xx_wait_ready (dev,0 );if (ret <0 ) {netdev_warn (dev->net,"device not ready in smsc75xx_bind\n" ); - goto err; + goto free_pdata; }smsc75xx_init_mac_address (dev);
@@ -1492,7 +1492,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret =smsc75xx_reset (dev);if (ret <0 ) {netdev_warn (dev->net,"smsc75xx_reset error %d\n" , ret); - goto err; + goto cancel_work; } dev->net->netdev_ops = &smsc75xx_netdev_ops;
@@ -1503,8 +1503,11 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->max_mtu =MAX_SINGLE_PACKET_SIZE ;return 0 ; -err: +cancel_work: +cancel_work_sync (&pdata->set_multicast); +free_pdata:kfree (pdata); + dev->data[0 ] =0 ;return ret; }
@@ -1515,7 +1518,6 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)cancel_work_sync (&pdata->set_multicast);netif_dbg (dev, ifdown, dev->net,"free pdata\n" );kfree (pdata); - pdata =NULL ; dev->data[0 ] =0 ; } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 68/178 net: fec_ptp: fix issue caused by refactor the fec_devtype
In reply to Greg Kroah-HartmanFrom: Joakim Zhang <[email protected]>
[ Upstream commit d23765646e71b43ed2b809930411ba5c0aadee7b ]
Commit da722186f654 ("net: fec: set GPR bit on suspend by DT configuration.") refactor the fec_devtype, need adjust ptp driver accordingly.
--- drivers/net/ethernet/freescale/fec_ptp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/freescale/fec_ptp.c +1 -3
@@ -215,15 +215,13 @@ static u64 fec_ptp_read(const struct cyclecounter *cc) {struct fec_enet_private *fep = container_of(cc, struct fec_enet_private, cc); -const struct platform_device_id *id_entry = -platform_get_device_id (fep->pdev);u32 tempval; tempval =readl (fep->hwp +FEC_ATIME_CTRL ); tempval |=FEC_T_CTRL_CAPTURE ;writel (tempval, fep->hwp +FEC_ATIME_CTRL ); -if (id_entry->driver_data &FEC_QUIRK_BUG_CAPTURE ) +if (fep->quirks &FEC_QUIRK_BUG_CAPTURE )udelay (1 );return readl (fep->hwp +FEC_ATIME );
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 69/178 net: ipv4: fix memory leak in ip_mc_add1_src
In reply to Greg Kroah-HartmanFrom: Chengyang Fan <[email protected]>
[ Upstream commit d8e2973029b8b2ce477b564824431f3385c77083 ]
BUG: memory leak
unreferenced object 0xffff888101bc4c00 (size 32):
comm "syz-executor527", pid 360, jiffies 4294807421 (age 19.329s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01 00 00 00 00 00 00 00 ac 14 14 bb 00 00 02 00 ................
backtrace:
[<00000000f17c5244>] kmalloc include/linux/slab.h:558 [inline]
[<00000000f17c5244>] kzalloc include/linux/slab.h:688 [inline]
[<00000000f17c5244>] ip_mc_add1_src net/ipv4/igmp.c:1971 [inline]
[<00000000f17c5244>] ip_mc_add_src+0x95f/0xdb0 net/ipv4/igmp.c:2095
[<000000001cb99709>] ip_mc_source+0x84c/0xea0 net/ipv4/igmp.c:2416
[<0000000052cf19ed>] do_ip_setsockopt net/ipv4/ip_sockglue.c:1294 [inline]
[<0000000052cf19ed>] ip_setsockopt+0x114b/0x30c0 net/ipv4/ip_sockglue.c:1423
[<00000000477edfbc>] raw_setsockopt+0x13d/0x170 net/ipv4/raw.c:857
[<00000000e75ca9bb>] __sys_setsockopt+0x158/0x270 net/socket.c:2117
[<00000000bdb993a8>] __do_sys_setsockopt net/socket.c:2128 [inline]
[<00000000bdb993a8>] __se_sys_setsockopt net/socket.c:2125 [inline]
[<00000000bdb993a8>] __x64_sys_setsockopt+0xba/0x150 net/socket.c:2125
[<000000006a1ffdbd>] do_syscall_64+0x40/0x80 arch/x86/entry/common.c:47
[<00000000b11467c4>] entry_SYSCALL_64_after_hwframe+0x44/0xaeIn commit 24803f38a5c0 ("igmp: do not remove igmp souce list info when set link down"), the ip_mc_clear_src() in ip_mc_destroy_dev() was removed, because it was also called in igmpv3_clear_delrec().
Rough callgraph:
inetdev_destroy
-> ip_mc_destroy_dev
-> igmpv3_clear_delrec
-> ip_mc_clear_src-> RCU_INIT_POINTER(dev->ip_ptr, NULL)
However, ip_mc_clear_src() called in igmpv3_clear_delrec() doesn't release in_dev->mc_list->sources. And RCU_INIT_POINTER() assigns the NULL to dev->ip_ptr. As a result, in_dev cannot be obtained through inetdev_by_index() and then in_dev->mc_list->sources cannot be released by ip_mc_del1_src() in the sock_close. Rough call sequence goes like:
sock_close
-> __sock_release
-> inet_release
-> ip_mc_drop_socket
-> inetdev_by_index
-> ip_mc_leave_src
-> ip_mc_del_src
-> ip_mc_del1_srcSo we still need to call ip_mc_clear_src() in ip_mc_destroy_dev() to free in_dev->mc_list->sources.
--- net/ipv4/igmp.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/igmp.c +1 -0
@@ -1801,6 +1801,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev)while ((i =rtnl_dereference (in_dev->mc_list)) !=NULL ) { in_dev->mc_list = i->next_rcu; in_dev->mc_count--; +ip_mc_clear_src (i);ip_ma_put (i); } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 70/178 net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit a494bd642d9120648b06bb7d28ce6d05f55a7819 ]
While unix_may_send(sk, osk) is called while osk is locked, it appears unix_release_sock() can overwrite unix_peer() after this lock has been released, making KCSAN unhappy.
Changing unix_release_sock() to access/change unix_peer() before lock is released should fix this issue.
BUG: KCSAN: data-race in unix_dgram_sendmsg / unix_release_sock
write to 0xffff88810465a338 of 8 bytes by task 20852 on cpu 1:
unix_release_sock+0x4ed/0x6e0 net/unix/af_unix.c:558 unix_release+0x2f/0x50 net/unix/af_unix.c:859 __sock_release net/socket.c:599 [inline] sock_close+0x6c/0x150 net/socket.c:1258 __fput+0x25b/0x4e0 fs/file_table.c:280 ____fput+0x11/0x20 fs/file_table.c:313 task_work_run+0xae/0x130 kernel/task_work.c:164 tracehook_notify_resume include/linux/tracehook.h:189 [inline] exit_to_user_mode_loop kernel/entry/common.c:175 [inline] exit_to_user_mode_prepare+0x156/0x190 kernel/entry/common.c:209 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x20/0x40 kernel/entry/common.c:302 do_syscall_64+0x56/0x90 arch/x86/entry/common.c:57 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffff88810465a338 of 8 bytes by task 20888 on cpu 0:
unix_may_send net/unix/af_unix.c:189 [inline] unix_dgram_sendmsg+0x923/0x1610 net/unix/af_unix.c:1712 sock_sendmsg_nosec net/socket.c:654 [inline] sock_sendmsg net/socket.c:674 [inline] ____sys_sendmsg+0x360/0x4d0 net/socket.c:2350 ___sys_sendmsg net/socket.c:2404 [inline] __sys_sendmmsg+0x315/0x4b0 net/socket.c:2490 __do_sys_sendmmsg net/socket.c:2519 [inline] __se_sys_sendmmsg net/socket.c:2516 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2516 do_syscall_64+0x4a/0x90 arch/x86/entry/common.c:47 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0xffff888167905400 -> 0x0000000000000000
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 20888 Comm: syz-executor.0 Not tainted 5.13.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
--- net/unix/af_unix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
net/unix/af_unix.c +4 -3
@@ -535,12 +535,14 @@ static void unix_release_sock(struct sock *sk, int embrion) u->path.mnt =NULL ; state = sk->sk_state; sk->sk_state =TCP_CLOSE ; + + skpair =unix_peer (sk); +unix_peer (sk) =NULL ; +unix_state_unlock (sk);wake_up_interruptible_all (&u->peer_wait); - skpair =unix_peer (sk); -if (skpair !=NULL ) {if (sk->sk_type ==SOCK_STREAM || sk->sk_type ==SOCK_SEQPACKET ) {unix_state_lock (skpair);
@@ -555,7 +557,6 @@ static void unix_release_sock(struct sock *sk, int embrion)unix_dgram_peer_wake_disconnect (sk, skpair);sock_put (skpair);/* It may now die */ -unix_peer (sk) =NULL ; }/* Try to flush out this socket. Throw out buffers at least */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 71/178 net/mlx5: Fix error path for set HCA defaults
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
[ Upstream commit 94a4b8414d3e91104873007b659252f855ee344a ]
In the case of the failure to execute mlx5_core_set_hca_defaults(), we used wrong goto label to execute error unwind flow.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +2 -1
@@ -1157,7 +1157,7 @@ static int mlx5_load(struct mlx5_core_dev *dev) err =mlx5_core_set_hca_defaults (dev);if (err) {mlx5_core_err (dev,"Failed to set hca defaults\n" ); - goto err_sriov; + goto err_set_hca; }mlx5_vhca_event_start (dev);
@@ -1190,6 +1190,7 @@ err_ec:mlx5_sf_hw_table_destroy (dev); err_vhca:mlx5_vhca_event_stop (dev); +err_set_hca:mlx5_cleanup_fs (dev); err_fs:mlx5_accel_tls_cleanup (dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 72/178 net/mlx5: Check that driver was probed prior attaching the device
In reply to Greg Kroah-HartmanFrom: Leon Romanovsky <[email protected]>
[ Upstream commit 2058cc9c8041fde9c0bdd8e868c72b137cff8563 ]
The device can be requested to be attached despite being not probed. This situation is possible if devlink reload races with module removal, and the following kernel panic is an outcome of such race.
mlx5_core 0000:00:09.0: firmware version: 4.7.9999
mlx5_core 0000:00:09.0: 0.000 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x255 link)
BUG: unable to handle page fault for address: fffffffffffffff0 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 3218067 P4D 3218067 PUD 321a067 PMD 0 Oops: 0000 [#1] SMP KASAN NOPTI CPU: 7 PID: 250 Comm: devlink Not tainted 5.12.0-rc2+ #2836 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:mlx5_attach_device+0x80/0x280 [mlx5_core] Code: f8 48 c1 e8 03 42 80 3c 38 00 0f 85 80 01 00 00 48 8b 45 68 48 8d 78 f0 48 89 fe 48 c1 ee 03 42 80 3c 3e 00 0f 85 70 01 00 00 <48> 8b 40 f0 48 85 c0 74 0d 48 89 ef ff d0 85 c0 0f 85 84 05 0e 00 RSP: 0018:ffff8880129675f0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000001 RCX: ffffffff827407f1 RDX: 1ffff110011336cf RSI: 1ffffffffffffffe RDI: fffffffffffffff0 RBP: ffff888008e0c000 R08: 0000000000000008 R09: ffffffffa0662ee7 R10: fffffbfff40cc5dc R11: 0000000000000000 R12: ffff88800ea002e0 R13: ffffed1001d459f7 R14: ffffffffa05ef4f8 R15: dffffc0000000000 FS: 00007f51dfeaf740(0000) GS:ffff88806d5c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: fffffffffffffff0 CR3: 000000000bc82006 CR4: 0000000000370ea0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: mlx5_load_one+0x117/0x1d0 [mlx5_core] devlink_reload+0x2d5/0x520 ? devlink_remote_reload_actions_performed+0x30/0x30 ? mutex_trylock+0x24b/0x2d0 ? devlink_nl_cmd_reload+0x62b/0x1070 devlink_nl_cmd_reload+0x66d/0x1070 ? devlink_reload+0x520/0x520 ? devlink_nl_pre_doit+0x64/0x4d0 genl_family_rcv_msg_doit+0x1e9/0x2f0 ? mutex_lock_io_nested+0x1130/0x1130 ? genl_family_rcv_msg_attrs_parse.constprop.0+0x240/0x240 ? security_capable+0x51/0x90 genl_rcv_msg+0x27f/0x4a0 ? genl_get_cmd+0x3c0/0x3c0 ? lock_acquire+0x1a9/0x6d0 ? devlink_reload+0x520/0x520 ? lock_release+0x6c0/0x6c0 netlink_rcv_skb+0x11d/0x340 ? genl_get_cmd+0x3c0/0x3c0 ? netlink_ack+0x9f0/0x9f0 ? lock_release+0x1f9/0x6c0 genl_rcv+0x24/0x40 netlink_unicast+0x433/0x700 ? netlink_attachskb+0x730/0x730 ? _copy_from_iter_full+0x178/0x650 ? __alloc_skb+0x113/0x2b0 netlink_sendmsg+0x6f1/0xbd0 ? netlink_unicast+0x700/0x700 ? netlink_unicast+0x700/0x700 sock_sendmsg+0xb0/0xe0 __sys_sendto+0x193/0x240 ? __x64_sys_getpeername+0xb0/0xb0 ? copy_page_range+0x2300/0x2300 ? __up_read+0x1a1/0x7b0 ? do_user_addr_fault+0x219/0xdc0 __x64_sys_sendto+0xdd/0x1b0 ? syscall_enter_from_user_mode+0x1d/0x50 do_syscall_64+0x2d/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f51dffb514a Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 76 c3 0f 1f 44 00 00 55 48 83 ec 30 44 89 4c RSP: 002b:00007ffcaef22e78 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f51dffb514a RDX: 0000000000000030 RSI: 000055750daf2440 RDI: 0000000000000003 RBP: 000055750daf2410 R08: 00007f51e0081200 R09: 000000000000000c R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 Modules linked in: mlx5_core(-) ptp pps_core ib_ipoib rdma_ucm rdma_cm iw_cm ib_cm ib_umad ib_uverbs ib_core [last unloaded: mlx5_ib] CR2: fffffffffffffff0 ---[ end trace 7789831bfe74fa42 ]---
--- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/dev.c +15 -0
@@ -323,6 +323,16 @@ int mlx5_attach_device(struct mlx5_core_dev *dev) } }else { adev = &priv->adev[i]->adev; + +/* Pay attention that this is not PCI driver that +* mlx5_core_dev is connected, but auxiliary driver. +* +* Here we can race of module unload with devlink +* reload, but we don't need to take extra lock because +* we are holding global mlx5_intf_mutex. +*/ +if (!adev->dev.driver) +continue ; adrv =to_auxiliary_drv (adev->dev.driver);if (adrv->resume)
@@ -353,6 +363,10 @@ void mlx5_detach_device(struct mlx5_core_dev *dev)continue ; adev = &priv->adev[i]->adev; +/* Auxiliary driver was unbind manually through sysfs */ +if (!adev->dev.driver) + goto skip_suspend; + adrv =to_auxiliary_drv (adev->dev.driver);if (adrv->suspend) {
@@ -360,6 +374,7 @@ void mlx5_detach_device(struct mlx5_core_dev *dev)continue ; } +skip_suspend:del_adev (&priv->adev[i]->adev); priv->adev[i] =NULL ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 73/178 net/mlx5: E-Switch, Read PF mac address
In reply to Greg Kroah-HartmanFrom: Parav Pandit <[email protected]>
[ Upstream commit bbc8222dc49db8d49add0f27bcac33f4b92193dc ]
External controller PF's MAC address is not read from the device during vport setup. Fail to read this results in showing all zeros to user while the factory programmed MAC is a valid value.
$ devlink port show eth1 -jp
{
"port": {
"pci/0000:03:00.0/196608": {
"type": "eth",
"netdev": "eth1",
"flavour": "pcipf",
"controller": 1,
"pfnum": 0,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:00:00"
}
}
}
}Hence, read it when enabling a vport.
After the fix,
$ devlink port show eth1 -jp
{
"port": {
"pci/0000:03:00.0/196608": {
"type": "eth",
"netdev": "eth1",
"flavour": "pcipf",
"controller": 1,
"pfnum": 0,
"splittable": false,
"function": {
"hw_addr": "98:03:9b:a0:60:11"
}
}
}
}--- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +6 -0
@@ -1308,6 +1308,12 @@ int mlx5_esw_vport_enable(struct mlx5_eswitch *esw, u16 vport_num, goto err_vhca_mapping; } +/* External controller host PF has factory programmed MAC. +* Read it from the device. +*/ +if (mlx5_core_is_ecpf (esw->dev) && vport_num ==MLX5_VPORT_PF ) +mlx5_query_nic_vport_mac_address (esw->dev, vport_num, true, vport->info.mac); +esw_vport_change_handle_locked (vport); esw->enabled_vports++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 74/178 net/mlx5: E-Switch, Allow setting GUID for host PF vport
In reply to Greg Kroah-HartmanFrom: Parav Pandit <[email protected]>
[ Upstream commit ca36fc4d77b35b8d142cf1ed0eae5ec2e071dc3c ]
E-switch should be able to set the GUID of host PF vport. Currently it returns an error. This results in below error when user attempts to configure MAC address of the PF of an external controller.
$ devlink port function set pci/0000:03:00.0/196608 \ hw_addr 00:00:00:11:22:33
mlx5_core 0000:03:00.0: mlx5_esw_set_vport_mac_locked:1876:(pid 6715):\
"Failed to set vport 0 node guid, err = -22.RDMA_CM will not function properly for this VF."
Check for zero vport is no longer needed.
--- drivers/net/ethernet/mellanox/mlx5/core/vport.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/vport.c +0 -2
@@ -465,8 +465,6 @@ int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev,void *in;int err; -if (!vport) -return -EINVAL ;if (!MLX5_CAP_GEN (mdev, vport_group_manager))return -EACCES ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 75/178 net/mlx5: SF_DEV, remove SF device on invalid state
In reply to Greg Kroah-HartmanFrom: Parav Pandit <[email protected]>
[ Upstream commit c7d6c19b3bde66d7aebbe93e0f9e6d9ff57fc3fa ]
When auxiliary bus autoprobe is disabled and SF is in ACTIVE state, on SF port deletion it transitions from ACTIVE->ALLOCATED->INVALID.
When VHCA event handler queries the state, it is already transition to INVALID state.
In this scenario, event handler missed to delete the SF device.
Fix it by deleting the SF when SF state is INVALID.
--- drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c +1 -0
@@ -153,6 +153,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_ sf_index = event->function_id -MLX5_CAP_GEN (table->dev, sf_base_id); sf_dev =xa_load (&table->devices, sf_index);switch (event->new_vhca_state) { +case MLX5_VHCA_STATE_INVALID :case MLX5_VHCA_STATE_ALLOCATED :if (sf_dev)mlx5_sf_dev_del (table->dev, sf_dev, sf_index);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 76/178 net/mlx5: DR, Fix STEv1 incorrect L3 decapsulation padding
In reply to Greg Kroah-HartmanFrom: Alex Vesker <[email protected]>
[ Upstream commit 65fb7d109abe3a1a9f1c2d3ba7e1249bc978d5f0 ]
Decapsulation L3 on small inner packets which are less than 64 Bytes was done incorrectly. In small packets there is an extra padding added in L2 which should not be included in L3 length. The issue was that after decapL3 the extra L2 padding caused an update on the L3 length.
To avoid this issue the new header is pushed to the beginning of the packet (offset 0) which should not cause a HW reparse and update the L3 length.
--- .../mellanox/mlx5/core/steering/dr_ste_v1.c | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c +16 -10
@@ -712,7 +712,11 @@ static int dr_ste_v1_set_action_decap_l3_list(void *data,if (hw_action_sz /DR_STE_ACTION_DOUBLE_SZ <DR_STE_DECAP_L3_ACTION_NUM )return -EINVAL ; -memcpy (padded_data, data, data_sz); + inline_data_sz = +MLX5_FLD_SZ_BYTES (ste_double_action_insert_with_inline_v1, inline_data); + +/* Add an alignment padding */ +memcpy (padded_data + data_sz % inline_data_sz, data, data_sz);/* Remove L2L3 outer headers */ MLX5_SET(ste_single_action_remove_header_v1, hw_action, action_id,
@@ -724,32 +728,34 @@ static int dr_ste_v1_set_action_decap_l3_list(void *data, hw_action +=DR_STE_ACTION_DOUBLE_SZ ; used_actions++;/* Remove and NOP are a single double action */ - inline_data_sz = -MLX5_FLD_SZ_BYTES (ste_double_action_insert_with_inline_v1, inline_data); +/* Point to the last dword of the header */ + data_ptr += (data_sz / inline_data_sz) * inline_data_sz; -/* Add the new header inline + 2 extra bytes */ +/* Add the new header using inline action 4Byte at a time, the header +* is added in reversed order to the beginning of the packet to avoid +* incorrect parsing by the HW. Since header is 14B or 18B an extra +* two bytes are padded and later removed. +*/ for (i =0 ; i < data_sz / inline_data_sz +1 ; i++) {void *addr_inline;MLX5_SET (ste_double_action_insert_with_inline_v1, hw_action, action_id,DR_STE_V1_ACTION_ID_INSERT_INLINE );/* The hardware expects here offset to words (2 bytes) */ -MLX5_SET (ste_double_action_insert_with_inline_v1, hw_action, start_offset, - i *2 ); +MLX5_SET (ste_double_action_insert_with_inline_v1, hw_action, start_offset,0 );/* Copy bytes one by one to avoid endianness problem */ addr_inline =MLX5_ADDR_OF (ste_double_action_insert_with_inline_v1, hw_action, inline_data); -memcpy (addr_inline, data_ptr, inline_data_sz); +memcpy (addr_inline, data_ptr - i * inline_data_sz, inline_data_sz); hw_action +=DR_STE_ACTION_DOUBLE_SZ ; - data_ptr += inline_data_sz; used_actions++; } -/* Remove 2 extra bytes */ +/* Remove first 2 extra bytes */ MLX5_SET (ste_single_action_remove_header_size_v1, hw_action, action_id,DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE ); -MLX5_SET (ste_single_action_remove_header_size_v1, hw_action, start_offset, data_sz /2 ); +MLX5_SET (ste_single_action_remove_header_size_v1, hw_action, start_offset,0 );/* The hardware expects here size in words (2 bytes) */ MLX5_SET (ste_single_action_remove_header_size_v1, hw_action, remove_size,1 ); used_actions++;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 77/178 net/mlx5e: Dont create devices during unload flow
In reply to Greg Kroah-HartmanFrom: Dmytro Linkin <[email protected]>
[ Upstream commit a5ae8fc9058e37437c8c1f82b3d412b4abd1b9e6 ]
Running devlink reload command for port in switchdev mode cause resources to corrupt: driver can't release allocated EQ and reclaim memory pages, because "rdma" auxiliary device had add CQs which blocks EQ from deletion.
Erroneous sequence happens during reload-down phase, and is following:
1. detach device - suspends auxiliary devices which support it, destroys others. During this step "eth-rep" and "rdma-rep" are destroyed, "eth" - suspended.
2. disable SRIOV - moves device to legacy mode; as part of disablement - rescans drivers. This step adds "rdma" auxiliary device.
3. destroy EQ table - <failure>.
Driver shouldn't create any device during unload flows. To handle that implement MLX5_PRIV_FLAGS_DETACH flag, set it on device detach and unset on device attach. If flag is set do no-op on drivers rescan.
--- drivers/net/ethernet/mellanox/mlx5/core/dev.c | 4 ++++ include/linux/mlx5/driver.h | 4 ++++ 2 files changed, 8 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/dev.c +4 -0
@@ -306,6 +306,7 @@ int mlx5_attach_device(struct mlx5_core_dev *dev)int ret =0 , i;mutex_lock (&mlx5_intf_mutex); + priv->flags &= ~MLX5_PRIV_FLAGS_DETACH ;for (i =0 ; i <ARRAY_SIZE (mlx5_adev_devices); i++) {if (!priv->adev[i]) {bool is_supported = false;
@@ -378,6 +379,7 @@ skip_suspend:del_adev (&priv->adev[i]->adev); priv->adev[i] =NULL ; } + priv->flags |=MLX5_PRIV_FLAGS_DETACH ;mutex_unlock (&mlx5_intf_mutex); }
@@ -466,6 +468,8 @@ int mlx5_rescan_drivers_locked(struct mlx5_core_dev *dev)struct mlx5_priv *priv = &dev->priv;lockdep_assert_held (&mlx5_intf_mutex); +if (priv->flags &MLX5_PRIV_FLAGS_DETACH ) +return 0 ;delete_drivers (dev);if (priv->flags &MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV )
include/linux/mlx5/driver.h +4 -0
@@ -541,6 +541,10 @@ struct mlx5_core_roce {enum {MLX5_PRIV_FLAGS_DISABLE_IB_ADEV =1 <<0 ,MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV =1 <<1 , +/* Set during device detach to block any further devices +* creation/deletion on drivers rescan. Unset during device attach. +*/ +MLX5_PRIV_FLAGS_DETACH =1 <<2 , };struct mlx5_adev {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 78/178 net/mlx5: Reset mkey index on creation
In reply to Greg Kroah-HartmanFrom: Aya Levin <[email protected]>
[ Upstream commit 0232fc2ddcf4ffe01069fd1aa07922652120f44a ]
Reset only the index part of the mkey and keep the variant part. On devlink reload, driver recreates mkeys, so the mkey index may change. Trying to preserve the variant part of the mkey, driver mistakenly merged the mkey index with current value. In case of a devlink reload, current value of index part is dirty, so the index may be corrupted.
--- drivers/net/ethernet/mellanox/mlx5/core/mr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/mr.c +1 -1
@@ -54,7 +54,7 @@ int mlx5_core_create_mkey(struct mlx5_core_dev *dev, mkey_index =MLX5_GET (create_mkey_out, lout, mkey_index); mkey->iova =MLX5_GET64 (mkc, mkc, start_addr); mkey->size =MLX5_GET64 (mkc, mkc, len); - mkey->key |=mlx5_idx_to_mkey (mkey_index); + mkey->key = (u32 )mlx5_mkey_variant (mkey->key) |mlx5_idx_to_mkey (mkey_index); mkey->pd =MLX5_GET (mkc, mkc, pd);init_waitqueue_head (&mkey->wait);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 79/178 be2net: Fix an error handling path in be_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit c19c8c0e666f9259e2fc4d2fa4b9ff8e3b40ee5d ]
If an error occurs after a 'pci_enable_pcie_error_reporting()' call, it must be undone by a corresponding 'pci_disable_pcie_error_reporting()' call, as already done in the remove function.
--- drivers/net/ethernet/emulex/benet/be_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/emulex/benet/be_main.c +1 -0
@@ -5897,6 +5897,7 @@ drv_cleanup: unmap_bars:be_unmap_pci_bars (adapter); free_netdev: +pci_disable_pcie_error_reporting (pdev);free_netdev (netdev); rel_reg:pci_release_regions (pdev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 80/178 net: hamradio: fix memory leak in mkiss_close
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit 7edcc682301492380fbdd604b4516af5ae667a13 ]
My local syzbot instance hit memory leak in mkiss_open()[1]. The problem was in missing free_netdev() in mkiss_close().
In mkiss_open() netdevice is allocated and then registered, but in mkiss_close() netdevice was only unregistered, but not freed.
Fail log:
BUG: memory leak
unreferenced object 0xffff8880281ba000 (size 4096):
comm "syz-executor.1", pid 11443, jiffies 4295046091 (age 17.660s)
hex dump (first 32 bytes):
61 78 30 00 00 00 00 00 00 00 00 00 00 00 00 00 ax0.............
00 27 fa 2a 80 88 ff ff 00 00 00 00 00 00 00 00 .'.*............
backtrace:
[<ffffffff81a27201>] kvmalloc_node+0x61/0xf0
[<ffffffff8706e7e8>] alloc_netdev_mqs+0x98/0xe80
[<ffffffff84e64192>] mkiss_open+0xb2/0x6f0 [1]
[<ffffffff842355db>] tty_ldisc_open+0x9b/0x110
[<ffffffff84236488>] tty_set_ldisc+0x2e8/0x670
[<ffffffff8421f7f3>] tty_ioctl+0xda3/0x1440
[<ffffffff81c9f273>] __x64_sys_ioctl+0x193/0x200
[<ffffffff8911263a>] do_syscall_64+0x3a/0xb0
[<ffffffff89200068>] entry_SYSCALL_64_after_hwframe+0x44/0xae
BUG: memory leak
unreferenced object 0xffff8880141a9a00 (size 96):
comm "syz-executor.1", pid 11443, jiffies 4295046091 (age 17.660s)
hex dump (first 32 bytes):
e8 a2 1b 28 80 88 ff ff e8 a2 1b 28 80 88 ff ff ...(.......(....
98 92 9c aa b0 40 02 00 00 00 00 00 00 00 00 00 .....@..........
backtrace:
[<ffffffff8709f68b>] __hw_addr_create_ex+0x5b/0x310
[<ffffffff8709fb38>] __hw_addr_add_ex+0x1f8/0x2b0
[<ffffffff870a0c7b>] dev_addr_init+0x10b/0x1f0
[<ffffffff8706e88b>] alloc_netdev_mqs+0x13b/0xe80
[<ffffffff84e64192>] mkiss_open+0xb2/0x6f0 [1]
[<ffffffff842355db>] tty_ldisc_open+0x9b/0x110
[<ffffffff84236488>] tty_set_ldisc+0x2e8/0x670
[<ffffffff8421f7f3>] tty_ioctl+0xda3/0x1440
[<ffffffff81c9f273>] __x64_sys_ioctl+0x193/0x200
[<ffffffff8911263a>] do_syscall_64+0x3a/0xb0
[<ffffffff89200068>] entry_SYSCALL_64_after_hwframe+0x44/0xae
BUG: memory leak
unreferenced object 0xffff8880219bfc00 (size 512):
comm "syz-executor.1", pid 11443, jiffies 4295046091 (age 17.660s)
hex dump (first 32 bytes):
00 a0 1b 28 80 88 ff ff 80 8f b1 8d ff ff ff ff ...(............
80 8f b1 8d ff ff ff ff 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff81a27201>] kvmalloc_node+0x61/0xf0
[<ffffffff8706eec7>] alloc_netdev_mqs+0x777/0xe80
[<ffffffff84e64192>] mkiss_open+0xb2/0x6f0 [1]
[<ffffffff842355db>] tty_ldisc_open+0x9b/0x110
[<ffffffff84236488>] tty_set_ldisc+0x2e8/0x670
[<ffffffff8421f7f3>] tty_ioctl+0xda3/0x1440
[<ffffffff81c9f273>] __x64_sys_ioctl+0x193/0x200
[<ffffffff8911263a>] do_syscall_64+0x3a/0xb0
[<ffffffff89200068>] entry_SYSCALL_64_after_hwframe+0x44/0xae
BUG: memory leak
unreferenced object 0xffff888029b2b200 (size 256):
comm "syz-executor.1", pid 11443, jiffies 4295046091 (age 17.660s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace:
[<ffffffff81a27201>] kvmalloc_node+0x61/0xf0
[<ffffffff8706f062>] alloc_netdev_mqs+0x912/0xe80
[<ffffffff84e64192>] mkiss_open+0xb2/0x6f0 [1]
[<ffffffff842355db>] tty_ldisc_open+0x9b/0x110
[<ffffffff84236488>] tty_set_ldisc+0x2e8/0x670
[<ffffffff8421f7f3>] tty_ioctl+0xda3/0x1440
[<ffffffff81c9f273>] __x64_sys_ioctl+0x193/0x200
[<ffffffff8911263a>] do_syscall_64+0x3a/0xb0
[<ffffffff89200068>] entry_SYSCALL_64_after_hwframe+0x44/0xae--- drivers/net/hamradio/mkiss.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/hamradio/mkiss.c +1 -0
@@ -799,6 +799,7 @@ static void mkiss_close(struct tty_struct *tty) ax->tty =NULL ;unregister_netdev (ax->dev); +free_netdev (ax->dev); }/* Perform I/O control on an active ax25 channel. */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 81/178 net: cdc_eem: fix tx fixup skb leak
In reply to Greg Kroah-HartmanFrom: Linyu Yuan <[email protected]>
[ Upstream commit c3b26fdf1b32f91c7a3bc743384b4a298ab53ad7 ]
when usbnet transmit a skb, eem fixup it in eem_tx_fixup(), if skb_copy_expand() failed, it return NULL, usbnet_start_xmit() will have no chance to free original skb.
fix it by free orginal skb in eem_tx_fixup() first, then check skb clone status, if failed, return NULL to usbnet.
--- drivers/net/usb/cdc_eem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/cdc_eem.c +1 -1
@@ -123,10 +123,10 @@ static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } skb2 =skb_copy_expand (skb,EEM_HEAD ,ETH_FCS_LEN + padlen, flags); +dev_kfree_skb_any (skb);if (!skb2)return NULL ; -dev_kfree_skb_any (skb); skb = skb2; done:
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 82/178 cxgb4: fix wrong shift.
In reply to Greg Kroah-HartmanFrom: Pavel Machek <[email protected]>
[ Upstream commit 39eb028183bc7378bb6187067e20bf6d8c836407 ]
While fixing coverity warning, commit dd2c79677375 introduced typo in shift value. Fix that.
--- drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +1 -1
@@ -198,7 +198,7 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f,WORD_MASK , f->fs.nat_lip[3 ] | f->fs.nat_lip[2 ] <<8 | f->fs.nat_lip[1 ] <<16 | - (u64)f->fs.nat_lip[0] << 25, 1); + (u64)f->fs.nat_lip[0] << 24, 1); } }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 83/178 bnxt_en: Rediscover PHY capabilities after firmware reset
In reply to Greg Kroah-HartmanFrom: Michael Chan <[email protected]>
[ Upstream commit 0afd6a4e8028cc487c240b6cfe04094e45a306e4 ]
There is a missing bnxt_probe_phy() call in bnxt_fw_init_one() to rediscover the PHY capabilities after a firmware reset. This can cause some PHY related functionalities to fail after a firmware reset. For example, in multi-host, the ability for any host to configure the PHY settings may be lost after a firmware reset.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +5 -0
@@ -11573,6 +11573,8 @@ static void bnxt_fw_init_one_p3(struct bnxt *bp)bnxt_hwrm_coal_params_qcaps (bp); } +static int bnxt_probe_phy (struct bnxt *bp,bool fw_dflt); +static int bnxt_fw_init_one (struct bnxt *bp) {int rc;
@@ -11587,6 +11589,9 @@ static int bnxt_fw_init_one(struct bnxt *bp)netdev_err (bp->dev,"Firmware init phase 2 failed\n" );return rc; } + rc =bnxt_probe_phy (bp, false); +if (rc) +return rc; rc =bnxt_approve_mac (bp, bp->dev->dev_addr, false);if (rc)return rc;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 84/178 bnxt_en: Fix TQM fastpath ring backing store computation
In reply to Greg Kroah-HartmanFrom: Rukhsana Ansari <[email protected]>
[ Upstream commit c12e1643d2738bcd4e26252ce531878841dd3f38 ]
TQM fastpath ring needs to be sized to store both the requester and responder side of RoCE QPs in TQM for supporting bi-directional tests. Fix bnxt_alloc_ctx_mem() to multiply the RoCE QPs by a factor of 2 when computing the number of entries for TQM fastpath ring. This fixes an RX pipeline stall issue when running bi-directional max RoCE QP tests.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -7295,7 +7295,7 @@ skip_rdma: entries_sp = ctx->vnic_max_vnic_entries + ctx->qp_max_l2_entries +2 * (extra_qps + ctx->qp_min_qp1_entries) + min; entries_sp =roundup (entries_sp, ctx->tqm_entries_multiple); - entries = ctx->qp_max_l2_entries + extra_qps + ctx->qp_min_qp1_entries; + entries = ctx->qp_max_l2_entries +2 * (extra_qps + ctx->qp_min_qp1_entries); entries =roundup (entries, ctx->tqm_entries_multiple); entries =clamp_t (u32, entries, min, ctx->tqm_max_entries_per_ring);for (i =0 ; i < ctx->tqm_fp_rings_count +1 ; i++) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 85/178 bnxt_en: Call bnxt_ethtool_free() in bnxt_init_one() error path
In reply to Greg Kroah-HartmanFrom: Somnath Kotur <[email protected]>
[ Upstream commit 03400aaa69f916a376e11526cf591901a96a3a5c ]
bnxt_ethtool_init() may have allocated some memory and we need to call bnxt_ethtool_free() to properly unwind if bnxt_init_one() fails.
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -0
@@ -12981,6 +12981,7 @@ init_err_pci_clean:bnxt_hwrm_func_drv_unrgtr (bp);bnxt_free_hwrm_short_cmd_req (bp);bnxt_free_hwrm_resources (bp); +bnxt_ethtool_free (bp);kfree (bp->fw_health); bp->fw_health =NULL ;bnxt_cleanup_pci (bp);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 86/178 icmp: dont send out ICMP messages with a source address of 0.0.0.0
In reply to Greg Kroah-HartmanFrom: Toke Høiland-Jørgensen <[email protected]>
[ Upstream commit 321827477360934dc040e9d3c626bf1de6c3ab3c ]
When constructing ICMP response messages, the kernel will try to pick a suitable source address for the outgoing packet. However, if no IPv4 addresses are configured on the system at all, this will fail and we end up producing an ICMP message with a source address of 0.0.0.0. This can happen on a box routing IPv4 traffic via v6 nexthops, for instance.
Since 0.0.0.0 is not generally routable on the internet, there's a good chance that such ICMP messages will never make it back to the sender of the original packet that the ICMP message was sent in response to. This, in turn, can create connectivity and PMTUd problems for senders. Fortunately, RFC7600 reserves a dummy address to be used as a source for ICMP messages (192.0.0.8/32), so let's teach the kernel to substitute that address as a last resort if the regular source address selection procedure fails.
Below is a quick example reproducing this issue with network namespaces:
ip netns add ns0
ip l add type veth peer netns ns0
ip l set dev veth0 up
ip a add 10.0.0.1/24 dev veth0
ip a add fc00:dead:cafe:42::1/64 dev veth0
ip r add 10.1.0.0/24 via inet6 fc00:dead:cafe:42::2
ip -n ns0 l set dev veth0 up
ip -n ns0 a add fc00:dead:cafe:42::2/64 dev veth0
ip -n ns0 r add 10.0.0.0/24 via inet6 fc00:dead:cafe:42::1
ip netns exec ns0 sysctl -w net.ipv4.icmp_ratelimit=0
ip netns exec ns0 sysctl -w net.ipv4.ip_forward=1
tcpdump -tpni veth0 -c 2 icmp &
ping -w 1 10.1.0.1 > /dev/null
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode listening on veth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes IP 10.0.0.1 > 10.1.0.1: ICMP echo request, id 29, seq 1, length 64 IP 0.0.0.0 > 10.0.0.1: ICMP net 10.1.0.1 unreachable, length 92
2 packets captured
2 packets received by filter
0 packets dropped by kernel
With this patch the above capture changes to:
IP 10.0.0.1 > 10.1.0.1: ICMP echo request, id 31127, seq 1, length 64 IP 192.0.0.8 > 10.0.0.1: ICMP net 10.1.0.1 unreachable, length 92
--- include/uapi/linux/in.h | 3 +++ net/ipv4/icmp.c | 7 +++++++ 2 files changed, 10 insertions(+)
include/uapi/linux/in.h +3 -0
@@ -289,6 +289,9 @@ struct sockaddr_in {/* Address indicating an error return. */ #define INADDR_NONE ((unsigned long int) 0xffffffff) +/* Dummy address for src of ICMP replies if no real address is set (RFC7600). */ +#define INADDR_DUMMY ((unsigned long int) 0xc0000008) +/* Network number for local host loopback. */ #define IN_LOOPBACKNET 127
net/ipv4/icmp.c +7 -0
@@ -759,6 +759,13 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, icmp_param.data_len = room; icmp_param.head_len =sizeof (struct icmphdr ); +/* if we don't have a source address at this point, fall back to the +* dummy address instead of sending out a packet with a source address +* of 0.0.0.0 +*/ +if (!fl4.saddr) + fl4.saddr =htonl (INADDR_DUMMY ); +icmp_push_reply (&icmp_param, &fl4, &ipc, &rt); ende:ip_rt_put (rt);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 87/178 net: ethernet: fix potential use-after-free in ec_bhf_remove
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
[ Upstream commit 9cca0c2d70149160407bda9a9446ce0c29b6e6c6 ]
static void ec_bhf_remove(struct pci_dev *dev)
{
...
struct ec_bhf_priv *priv = netdev_priv(net_dev); unregister_netdev(net_dev); free_netdev(net_dev); pci_iounmap(dev, priv->dma_io); pci_iounmap(dev, priv->io);
...
}
priv is netdev private data, but it is used
after free_netdev(). It can cause use-after-free when accessing priv pointer. So, fix it by moving free_netdev() after pci_iounmap() calls.
--- drivers/net/ethernet/ec_bhf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/ec_bhf.c +3 -1
@@ -576,10 +576,12 @@ static void ec_bhf_remove(struct pci_dev *dev)struct ec_bhf_priv *priv =netdev_priv (net_dev);unregister_netdev (net_dev); -free_netdev (net_dev);pci_iounmap (dev, priv->dma_io);pci_iounmap (dev, priv->io); + +free_netdev (net_dev); +pci_release_regions (dev);pci_clear_master (dev);pci_disable_device (dev);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 88/178 regulator: cros-ec: Fix error code in dev_err message
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit 3d681804efcb6e5d8089a433402e19179347d7ae ]
Show proper error code instead of 0.
--- drivers/regulator/cros-ec-regulator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/regulator/cros-ec-regulator.c +2 -1
@@ -225,8 +225,9 @@ static int cros_ec_regulator_probe(struct platform_device *pdev) drvdata->dev =devm_regulator_register (dev, &drvdata->desc, &cfg);if (IS_ERR (drvdata->dev)) { + ret =PTR_ERR (drvdata->dev);dev_err (&pdev->dev,"Failed to register regulator: %d\n" , ret); -return PTR_ERR (drvdata->dev); +return ret; }platform_set_drvdata (pdev, drvdata);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 89/178 regulator: max77620: Silence deferred probe error
In reply to Greg Kroah-HartmanFrom: Dmitry Osipenko <[email protected]>
[ Upstream commit 62499a94ce5b9a41047dbadaad885347b1176079 ]
One of previous changes to regulator core causes PMIC regulators to re-probe until supply regulator is registered. Silence noisy error message about the deferred probe.
--- drivers/regulator/max77620-regulator.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/regulator/max77620-regulator.c +4 -6
@@ -846,12 +846,10 @@ static int max77620_regulator_probe(struct platform_device *pdev)return ret; rdev =devm_regulator_register (dev, rdesc, &config); -if (IS_ERR (rdev)) { - ret =PTR_ERR (rdev); -dev_err (dev,"Regulator registration %s failed: %d\n" , - rdesc->name, ret); -return ret; - } +if (IS_ERR (rdev)) +return dev_err_probe (dev,PTR_ERR (rdev), +"Regulator registration %s failed\n" , + rdesc->name); }return 0 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 90/178 regulator: bd70528: Fix off-by-one for buck123 .n_voltages setting
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit 0514582a1a5b4ac1a3fd64792826d392d7ae9ddc ]
The valid selectors for bd70528 bucks are 0 ~ 0xf, so the .n_voltages should be 16 (0x10). Use 0x10 to make it consistent with BD70528_LDO_VOLTS. Also remove redundant defines for BD70528_BUCK_VOLTS.
--- include/linux/mfd/rohm-bd70528.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
include/linux/mfd/rohm-bd70528.h +1 -3
@@ -26,9 +26,7 @@ struct bd70528_data {struct mutex rtc_timer_lock; }; -#define BD70528_BUCK_VOLTS 17 -#define BD70528_BUCK_VOLTS 17 -#define BD70528_BUCK_VOLTS 17 +#define BD70528_BUCK_VOLTS 0x10#define BD70528_LDO_VOLTS 0x20#define BD70528_REG_BUCK1_EN 0x0F
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 91/178 platform/x86: thinkpad_acpi: Add X1 Carbon Gen 9 second fan support
In reply to Greg Kroah-HartmanFrom: Til Jasper Ullrich <[email protected]>
[ Upstream commit c0e0436cb4f6627146acdae8c77828f18db01151 ]
The X1 Carbon Gen 9 uses two fans instead of one like the previous generation. This adds support for the second fan. It has been tested on my X1 Carbon Gen 9 (20XXS00100) and works fine.
--- drivers/platform/x86/thinkpad_acpi.c | 1 + 1 file changed, 1 insertion(+)
drivers/platform/x86/thinkpad_acpi.c +1 -0
@@ -8808,6 +8808,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {TPACPI_Q_LNV3 ('N' ,'2' ,'O' ,TPACPI_FAN_2CTL ),/* P1 / X1 Extreme (2nd gen) */ TPACPI_Q_LNV3 ('N' ,'2' ,'V' ,TPACPI_FAN_2CTL ),/* P1 / X1 Extreme (3nd gen) */ TPACPI_Q_LNV3 ('N' ,'3' ,'0' ,TPACPI_FAN_2CTL ),/* P15 (1st gen) / P15v (1st gen) */ + TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL), /* X1 Carbon (9th gen) */ };static int __init fan_init (struct ibm_init_struct *iibm)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 92/178 ASoC: rt5659: Fix the lost powers for the HDA header
In reply to Greg Kroah-HartmanFrom: Jack Yu <[email protected]>
[ Upstream commit 6308c44ed6eeadf65c0a7ba68d609773ed860fbb ]
The power of "LDO2", "MICBIAS1" and "Mic Det Power" were powered off after the DAPM widgets were added, and these powers were set by the JD settings "RT5659_JD_HDA_HEADER" in the probe function. In the codec probe function, these powers were ignored to prevent them controlled by DAPM.
Message-Id: <[email protected]>
--- sound/soc/codecs/rt5659.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
sound/soc/codecs/rt5659.c +21 -5
@@ -2433,13 +2433,18 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,return 0 ; } -static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { +static const struct snd_soc_dapm_widget rt5659_particular_dapm_widgets[] = {SND_SOC_DAPM_SUPPLY ("LDO2" ,RT5659_PWR_ANLG_3 ,RT5659_PWR_LDO2_BIT ,0 ,NULL ,0 ), -SND_SOC_DAPM_SUPPLY ("PLL" ,RT5659_PWR_ANLG_3 ,RT5659_PWR_PLL_BIT ,0 , -NULL ,0 ), +SND_SOC_DAPM_SUPPLY ("MICBIAS1" ,RT5659_PWR_ANLG_2 ,RT5659_PWR_MB1_BIT , +0 ,NULL ,0 ),SND_SOC_DAPM_SUPPLY ("Mic Det Power" ,RT5659_PWR_VOL ,RT5659_PWR_MIC_DET_BIT ,0 ,NULL ,0 ), +}; + +static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { +SND_SOC_DAPM_SUPPLY ("PLL" ,RT5659_PWR_ANLG_3 ,RT5659_PWR_PLL_BIT ,0 , +NULL ,0 ),SND_SOC_DAPM_SUPPLY ("Mono Vref" ,RT5659_PWR_ANLG_1 ,RT5659_PWR_VREF3_BIT ,0 ,NULL ,0 ),
@@ -2464,8 +2469,6 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { RT5659_ADC_MONO_R_ASRC_SFT, 0, NULL, 0),/* Input Side */ -SND_SOC_DAPM_SUPPLY ("MICBIAS1" ,RT5659_PWR_ANLG_2 ,RT5659_PWR_MB1_BIT , -0 ,NULL ,0 ),SND_SOC_DAPM_SUPPLY ("MICBIAS2" ,RT5659_PWR_ANLG_2 ,RT5659_PWR_MB2_BIT ,0 ,NULL ,0 ), SND_SOC_DAPM_SUPPLY("MICBIAS3", RT5659_PWR_ANLG_2, RT5659_PWR_MB3_BIT,
@@ -3660,10 +3663,23 @@ static int rt5659_set_bias_level(struct snd_soc_component *component,static int rt5659_probe (struct snd_soc_component *component) { +struct snd_soc_dapm_context *dapm = +snd_soc_component_get_dapm (component);struct rt5659_priv *rt5659 =snd_soc_component_get_drvdata (component); rt5659->component = component; +switch (rt5659->pdata.jd_src) { +case RT5659_JD_HDA_HEADER : +break ; + +default : +snd_soc_dapm_new_controls (dapm, + rt5659_particular_dapm_widgets, +ARRAY_SIZE (rt5659_particular_dapm_widgets)); +break ; + } +return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 93/178 phy: phy-mtk-tphy: Fix some resource leaks in mtk_phy_init()
In reply to Greg Kroah-HartmanFrom: Tiezhu Yang <[email protected]>
[ Upstream commit aaac9a1bd370338ce372669eb9a6059d16b929aa ]
Use clk_disable_unprepare() in the error path of mtk_phy_init() to fix some resource leaks.
--- drivers/phy/mediatek/phy-mtk-tphy.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/phy/mediatek/phy-mtk-tphy.c +2 -0
@@ -949,6 +949,8 @@ static int mtk_phy_init(struct phy *phy)break ;default :dev_err (tphy->dev,"incompatible PHY type\n" ); +clk_disable_unprepare (instance->ref_clk); +clk_disable_unprepare (instance->da_ref_clk);return -EINVAL ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 94/178 ASoC: fsl-asoc-card: Set .owner attribute when registering card.
In reply to Greg Kroah-HartmanFrom: Nicolas Cavallari <[email protected]>
[ Upstream commit a8437f05384cb472518ec21bf4fffbe8f0a47378 ]
Otherwise, when compiled as module, a WARN_ON is triggered:
WARNING: CPU: 0 PID: 5 at sound/core/init.c:208 snd_card_new+0x310/0x39c [snd] [...] CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.10.39 #1 Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) Workqueue: events deferred_probe_work_func [<c0111988>] (unwind_backtrace) from [<c010c8ac>] (show_stack+0x10/0x14) [<c010c8ac>] (show_stack) from [<c092784c>] (dump_stack+0xdc/0x104) [<c092784c>] (dump_stack) from [<c0129710>] (__warn+0xd8/0x114) [<c0129710>] (__warn) from [<c0922a48>] (warn_slowpath_fmt+0x5c/0xc4) [<c0922a48>] (warn_slowpath_fmt) from [<bf0496f8>] (snd_card_new+0x310/0x39c [snd]) [<bf0496f8>] (snd_card_new [snd]) from [<bf1d7df8>] (snd_soc_bind_card+0x334/0x9c4 [snd_soc_core]) [<bf1d7df8>] (snd_soc_bind_card [snd_soc_core]) from [<bf1e9cd8>] (devm_snd_soc_register_card+0x30/0x6c [snd_soc_core]) [<bf1e9cd8>] (devm_snd_soc_register_card [snd_soc_core]) from [<bf22d964>] (fsl_asoc_card_probe+0x550/0xcc8 [snd_soc_fsl_asoc_card]) [<bf22d964>] (fsl_asoc_card_probe [snd_soc_fsl_asoc_card]) from [<c060c930>] (platform_drv_probe+0x48/0x98)
[...]
--- sound/soc/fsl/fsl-asoc-card.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/fsl/fsl-asoc-card.c +1 -0
@@ -732,6 +732,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)/* Initialize sound card */ priv->pdev = pdev; priv->card.dev = &pdev->dev; + priv->card.owner =THIS_MODULE ; ret =snd_soc_of_parse_card_name (&priv->card,"model" );if (ret) { snprintf(priv->name, sizeof(priv->name), "%s-audio",
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 95/178 regulator: mt6315: Fix function prototype for mt6315_map_mode
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit 89082179ec5028bcd58c87171e08ada035689542 ]
The .of_map_mode should has below function prototype:
unsigned int (*of_map_mode)(unsigned int mode);
--- drivers/regulator/mt6315-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/mt6315-regulator.c +1 -1
@@ -59,7 +59,7 @@ static const struct linear_range mt_volt_range1[] = { REGULATOR_LINEAR_RANGE(0, 0, 0xbf, 6250), }; -static unsigned int mt6315_map_mode (u32 mode) +static unsigned int mt6315_map_mode (unsigned int mode) {switch (mode) {case MT6315_BUCK_MODE_AUTO :
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 96/178 regulator: rtmv20: Fix to make regcache value first reading back from HW
In reply to Greg Kroah-HartmanFrom: ChiYuan Huang <[email protected]>
[ Upstream commit 46639a5e684edd0b80ae9dff220f193feb356277 ]
- Fix to make regcache value first reading back from HW.
--- drivers/regulator/rtmv20-regulator.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/regulator/rtmv20-regulator.c +2 -0
@@ -27,6 +27,7 @@#define RTMV20_REG_LDIRQ 0x30#define RTMV20_REG_LDSTAT 0x40#define RTMV20_REG_LDMASK 0x50 +#define RTMV20_MAX_REGS (RTMV20_REG_LDMASK + 1)#define RTMV20_VID_MASK GENMASK(7, 4)#define RICHTEK_VID 0x80
@@ -313,6 +314,7 @@ static const struct regmap_config rtmv20_regmap_config = { .val_bits = 8, .cache_type = REGCACHE_RBTREE, .max_register = RTMV20_REG_LDMASK, + .num_reg_defaults_raw = RTMV20_MAX_REGS, .writeable_reg = rtmv20_is_accessible_reg, .readable_reg = rtmv20_is_accessible_reg,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 97/178 spi: spi-zynq-qspi: Fix some wrong goto jumps & missing error code
In reply to Greg Kroah-HartmanFrom: zpershuai <[email protected]>
[ Upstream commit f131767eefc47de2f8afb7950cdea78397997d66 ]
In zynq_qspi_probe function, when enable the device clock is done, the return of all the functions should goto the clk_dis_all label.
If num_cs is not right then this should return a negative error code but currently it returns success.
--- drivers/spi/spi-zynq-qspi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/spi/spi-zynq-qspi.c +4 -3
@@ -678,14 +678,14 @@ static int zynq_qspi_probe(struct platform_device *pdev) xqspi->irq =platform_get_irq (pdev,0 );if (xqspi->irq <=0 ) { ret = -ENXIO ; - goto remove_master; + goto clk_dis_all; } ret =devm_request_irq (&pdev->dev, xqspi->irq, zynq_qspi_irq,0 , pdev->name, xqspi);if (ret !=0 ) { ret = -ENXIO ;dev_err (&pdev->dev,"request_irq failed\n" ); - goto remove_master; + goto clk_dis_all; } ret = of_property_read_u32(np, "num-cs",
@@ -693,8 +693,9 @@ static int zynq_qspi_probe(struct platform_device *pdev)if (ret <0 ) { ctlr->num_chipselect =1 ; }else if (num_cs >ZYNQ_QSPI_MAX_NUM_CS ) { + ret = -EINVAL ;dev_err (&pdev->dev,"only 2 chip selects are available\n" ); - goto remove_master; + goto clk_dis_all; }else { ctlr->num_chipselect = num_cs; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 98/178 sched/pelt: Ensure that *_sum is always synced with *_avg
In reply to Greg Kroah-HartmanFrom: Vincent Guittot <[email protected]>
[ Upstream commit fcf6631f3736985ec89bdd76392d3c7bfb60119f ]
Rounding in PELT calculation happening when entities are attached/detached of a cfs_rq can result into situations where util/runnable_avg is not null but util/runnable_sum is. This is normally not possible so we need to ensure that util/runnable_sum stays synced with util/runnable_avg.
detach_entity_load_avg() is the last place where we don't sync util/runnable_sum with util/runnbale_avg when moving some sched_entities
--- kernel/sched/fair.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
kernel/sched/fair.c +8 -2
@@ -3760,11 +3760,17 @@ static void attach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s*/ static void detach_entity_load_avg (struct cfs_rq *cfs_rq,struct sched_entity *se) { +/* +* cfs_rq->avg.period_contrib can be used for both cfs_rq and se. +* See ___update_load_avg() for details. +*/ +u32 divider =get_pelt_divider (&cfs_rq->avg); +dequeue_load_avg (cfs_rq, se);sub_positive (&cfs_rq->avg.util_avg, se->avg.util_avg); -sub_positive (&cfs_rq->avg.util_sum, se->avg.util_sum); + cfs_rq->avg.util_sum = cfs_rq->avg.util_avg * divider;sub_positive (&cfs_rq->avg.runnable_avg, se->avg.runnable_avg); -sub_positive (&cfs_rq->avg.runnable_sum, se->avg.runnable_sum); + cfs_rq->avg.runnable_sum = cfs_rq->avg.runnable_avg * divider;add_tg_cfs_propagate (cfs_rq, -se->avg.load_sum);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 99/178 ASoC: tas2562: Fix TDM_CFG0_SAMPRATE values
In reply to Greg Kroah-HartmanFrom: Richard Weinberger <[email protected]>
[ Upstream commit 8bef925e37bdc9b6554b85eda16ced9a8e3c135f ]
TAS2562_TDM_CFG0_SAMPRATE_MASK starts at bit 1, not 0. So all values need to be left shifted by 1.
--- sound/soc/codecs/tas2562.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
sound/soc/codecs/tas2562.h +7 -7
@@ -57,13 +57,13 @@#define TAS2562_TDM_CFG0_RAMPRATE_MASK BIT(5)#define TAS2562_TDM_CFG0_RAMPRATE_44_1 BIT(5)#define TAS2562_TDM_CFG0_SAMPRATE_MASK GENMASK(3, 1) -#define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ 0x0 -#define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ 0x1 -#define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ 0x2 -#define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ 0x3 -#define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ 0x4 -#define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ 0x5 -#define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ 0x6 +#define TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ (0x0 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ (0x1 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ (0x2 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ (0x3 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ (0x4 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ (0x5 << 1) +#define TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ (0x6 << 1)#define TAS2562_TDM_CFG2_RIGHT_JUSTIFY BIT(6)
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 100/178 regulator: hi6421v600: Fix .vsel_mask setting
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit 50bec7fb4cb1bcf9d387046b6dec7186590791ec ]
Take ldo3_voltages as example, the ARRAY_SIZE(ldo3_voltages) is 16. i.e. the valid selector is 0 ~ 0xF.
But in current code the vsel_mask is "(1 << 15) - 1", i.e. 0x7FFF. Fix it.
--- drivers/staging/hikey9xx/hi6421v600-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/hikey9xx/hi6421v600-regulator.c +1 -1
@@ -83,7 +83,7 @@ static const unsigned int ldo34_voltages[] = { .owner = THIS_MODULE, \ .volt_table = vtable, \ .n_voltages = ARRAY_SIZE(vtable), \ - .vsel_mask = (1 << (ARRAY_SIZE(vtable) - 1)) - 1, \ + .vsel_mask = ARRAY_SIZE(vtable) - 1, \ .vsel_reg = vreg, \ .enable_reg = ereg, \ .enable_mask = emask, \
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 101/178 spi: stm32-qspi: Always wait BUSY bit to be cleared in stm32_qspi_wait_cmd()
In reply to Greg Kroah-HartmanFrom: Patrice Chotard <[email protected]>
[ Upstream commit d38fa9a155b2829b7e2cfcf8a4171b6dd3672808 ]
In U-boot side, an issue has been encountered when QSPI source clock is running at low frequency (24 MHz for example), waiting for TCF bit to be set didn't ensure that all data has been send out the FIFO, we should also wait that BUSY bit is cleared.
To prevent similar issue in kernel driver, we implement similar behavior by always waiting BUSY bit to be cleared.
--- drivers/spi/spi-stm32-qspi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/spi/spi-stm32-qspi.c +4 -1
@@ -293,7 +293,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi,int err =0 ;if (!op->data.nbytes) -return stm32_qspi_wait_nobusy (qspi); + goto wait_nobusy;if (readl_relaxed (qspi->io_base +QSPI_SR ) &SR_TCF ) goto out;
@@ -314,6 +314,9 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, out:/* clear flags */ writel_relaxed (FCR_CTCF |FCR_CTEF , qspi->io_base +QSPI_FCR ); +wait_nobusy: +if (!err) + err =stm32_qspi_wait_nobusy (qspi);return err; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 102/178 regulator: rt4801: Fix NULL pointer dereference if priv->enable_gpios is NULL
In reply to Greg Kroah-HartmanFrom: Axel Lin <[email protected]>
[ Upstream commit cb2381cbecb81a8893b2d1e1af29bc2e5531df27 ]
devm_gpiod_get_array_optional may return NULL if no GPIO was assigned.
--- drivers/regulator/rt4801-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/regulator/rt4801-regulator.c +2 -2
@@ -66,7 +66,7 @@ static int rt4801_enable(struct regulator_dev *rdev)struct gpio_descs *gpios = priv->enable_gpios;int id =rdev_get_id (rdev), ret; -if (gpios->ndescs <= id) { +if (!gpios || gpios->ndescs <= id) {dev_warn (&rdev->dev,"no dedicated gpio can control\n" ); goto bypass_gpio; }
@@ -88,7 +88,7 @@ static int rt4801_disable(struct regulator_dev *rdev)struct gpio_descs *gpios = priv->enable_gpios;int id =rdev_get_id (rdev); -if (gpios->ndescs <= id) { +if (!gpios || gpios->ndescs <= id) {dev_warn (&rdev->dev,"no dedicated gpio can control\n" ); goto bypass_gpio; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 103/178 ASoC: rt5682: Fix the fast discharge for headset unplugging in soundwire mode
In reply to Greg Kroah-HartmanFrom: Oder Chiou <[email protected]>
[ Upstream commit 49783c6f4a4f49836b5a109ae0daf2f90b0d7713 ]
Based on ("5a15cd7fce20b1fd4aece6a0240e2b58cd6a225d"), the setting also should be set in soundwire mode.
--- sound/soc/codecs/rt5682-sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/codecs/rt5682-sdw.c +2 -1
@@ -462,7 +462,8 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)regmap_update_bits (rt5682->regmap,RT5682_CBJ_CTRL_2 ,RT5682_EXT_JD_SRC ,RT5682_EXT_JD_SRC_MANUAL ); -regmap_write (rt5682->regmap,RT5682_CBJ_CTRL_1 ,0xd042 ); +regmap_write (rt5682->regmap,RT5682_CBJ_CTRL_1 ,0xd142 ); +regmap_update_bits (rt5682->regmap,RT5682_CBJ_CTRL_5 ,0x0700 ,0x0600 );regmap_update_bits (rt5682->regmap,RT5682_CBJ_CTRL_3 ,RT5682_CBJ_IN_BUF_EN ,RT5682_CBJ_IN_BUF_EN ); regmap_update_bits(rt5682->regmap, RT5682_SAR_IL_CMD_1,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 104/178 pinctrl: ralink: rt2880: avoid to error in calls is pin is already enabled
In reply to Greg Kroah-HartmanFrom: Sergio Paracuellos <[email protected]>
[ Upstream commit eb367d875f94a228c17c8538e3f2efcf2eb07ead ]
In 'rt2880_pmx_group_enable' driver is printing an error and returning -EBUSY if a pin has been already enabled. This begets anoying messages in the caller when this happens like the following:
rt2880-pinmux pinctrl: pcie is already enabled
mt7621-pci 1e140000.pcie: Error applying setting, reverse things back
To avoid this just print the already enabled message in the pinctrl driver and return 0 instead to not confuse the user with a real bad problem.
--- drivers/pinctrl/ralink/pinctrl-rt2880.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/ralink/pinctrl-rt2880.c +1 -1
@@ -127,7 +127,7 @@ static int rt2880_pmx_group_enable(struct pinctrl_dev *pctrldev,if (p->groups[group].enabled) {dev_err (p->dev,"%s is already enabled\n" , p->groups[group].name); -return -EBUSY ; +return 0 ; } p->groups[group].enabled =1 ;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 105/178 drm/sun4i: dw-hdmi: Make HDMI PHY into a platform device
In reply to Greg Kroah-HartmanFrom: Saravana Kannan <[email protected]>
[ Upstream commit 9bf3797796f570b34438235a6a537df85832bdad ]
On sunxi boards that use HDMI output, HDMI device probe keeps being avoided indefinitely with these repeated messages in dmesg:
platform 1ee0000.hdmi: probe deferral - supplier 1ef0000.hdmi-phy
not ready
There's a fwnode_link being created with fw_devlink=on between hdmi and hdmi-phy nodes, because both nodes have 'compatible' property set.
Fw_devlink code assumes that nodes that have compatible property set will also have a device associated with them by some driver eventually. This is not the case with the current sun8i-hdmi driver.
This commit makes sun8i-hdmi-phy into a proper platform device and fixes the display pipeline probe on sunxi boards that use HDMI.
More context: https://lkml.org/lkml/2021/5/16/203
--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 31 ++++++++++++++++--- drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 5 ++-- drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 41 ++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 11 deletions(-)
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +27 -4
@@ -209,7 +209,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, goto err_disable_clk_tmds; } - ret =sun8i_hdmi_phy_probe (hdmi, phy_node); + ret =sun8i_hdmi_phy_get (hdmi, phy_node);of_node_put (phy_node);if (ret) {dev_err (dev,"Couldn't get the HDMI PHY\n" );
@@ -242,7 +242,6 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, cleanup_encoder:drm_encoder_cleanup (encoder); -sun8i_hdmi_phy_remove (hdmi); err_disable_clk_tmds:clk_disable_unprepare (hdmi->clk_tmds); err_assert_ctrl_reset:
@@ -263,7 +262,6 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master,struct sun8i_dw_hdmi *hdmi =dev_get_drvdata (dev);dw_hdmi_unbind (hdmi->hdmi); -sun8i_hdmi_phy_remove (hdmi);clk_disable_unprepare (hdmi->clk_tmds);reset_control_assert (hdmi->rst_ctrl);gpiod_set_value (hdmi->ddc_en,0 );
@@ -320,7 +318,32 @@ static struct platform_driver sun8i_dw_hdmi_pltfm_driver = { .of_match_table = sun8i_dw_hdmi_dt_ids, }, }; -module_platform_driver (sun8i_dw_hdmi_pltfm_driver); + +static int __init sun8i_dw_hdmi_init (void ) +{ +int ret; + + ret =platform_driver_register (&sun8i_dw_hdmi_pltfm_driver); +if (ret) +return ret; + + ret =platform_driver_register (&sun8i_hdmi_phy_driver); +if (ret) { +platform_driver_unregister (&sun8i_dw_hdmi_pltfm_driver); +return ret; + } + +return ret; +} + +static void __exit sun8i_dw_hdmi_exit(void) +{ +platform_driver_unregister (&sun8i_dw_hdmi_pltfm_driver); +platform_driver_unregister (&sun8i_hdmi_phy_driver); +} + +module_init (sun8i_dw_hdmi_init); +module_exit (sun8i_dw_hdmi_exit);MODULE_AUTHOR ("Jernej Skrabec <[email protected]>" );MODULE_DESCRIPTION ("Allwinner DW HDMI bridge" );
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +3 -2
@@ -195,14 +195,15 @@ struct sun8i_dw_hdmi {struct gpio_desc *ddc_en; }; +extern struct platform_driver sun8i_hdmi_phy_driver; +static inline struct sun8i_dw_hdmi *encoder_to_sun8i_dw_hdmi (struct drm_encoder *encoder) { return container_of(encoder, struct sun8i_dw_hdmi, encoder); } -int sun8i_hdmi_phy_probe (struct sun8i_dw_hdmi *hdmi,struct device_node *node); -void sun8i_hdmi_phy_remove (struct sun8i_dw_hdmi *hdmi); +int sun8i_hdmi_phy_get (struct sun8i_dw_hdmi *hdmi,struct device_node *node);void sun8i_hdmi_phy_init (struct sun8i_hdmi_phy *phy); void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy,
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +36 -5
72 lines not on this page · raw message
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 106/178 ASoC: qcom: lpass-cpu: Fix pop noise during audio capture begin
In reply to Greg Kroah-HartmanFrom: Srinivasa Rao Mandadapu <[email protected]>
[ Upstream commit c8a4556d98510ca05bad8d02265a4918b03a8c0b ]
This patch fixes PoP noise of around 15ms observed during audio capture begin.
Enables BCLK and LRCLK in snd_soc_dai_ops prepare call for introducing some delay before capture start.
(am from https://patchwork.kernel.org/patch/12276369/)
(also found at https://lore.kernel.org/r/[email protected])
--- sound/soc/qcom/lpass-cpu.c | 79 ++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/lpass.h | 4 ++ 2 files changed, 83 insertions(+)
sound/soc/qcom/lpass-cpu.c +79 -0
@@ -93,8 +93,30 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) {struct lpass_data *drvdata =snd_soc_dai_get_drvdata (dai); +struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; +unsigned int id = dai->driver->id;clk_disable_unprepare (drvdata->mi2s_osr_clk[dai->driver->id]); +/* +* Ensure LRCLK is disabled even in device node validation. +* Will not impact if disabled in lpass_cpu_daiops_trigger() +* suspend. +*/ +if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) +regmap_fields_write (i2sctl->spken, id,LPAIF_I2SCTL_SPKEN_DISABLE ); +else +regmap_fields_write (i2sctl->micen, id,LPAIF_I2SCTL_MICEN_DISABLE ); + +/* +* BCLK may not be enabled if lpass_cpu_daiops_prepare is called before +* lpass_cpu_daiops_shutdown. It's paired with the clk_enable in +* lpass_cpu_daiops_prepare. +*/ +if (drvdata->mi2s_was_prepared[dai->driver->id]) { + drvdata->mi2s_was_prepared[dai->driver->id] = false; +clk_disable (drvdata->mi2s_bit_clk[dai->driver->id]); + } +clk_unprepare (drvdata->mi2s_bit_clk[dai->driver->id]); }
@@ -275,6 +297,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,case SNDRV_PCM_TRIGGER_START :case SNDRV_PCM_TRIGGER_RESUME :case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : +/* +* Ensure lpass BCLK/LRCLK is enabled during +* device resume as lpass_cpu_daiops_prepare() is not called +* after the device resumes. We don't check mi2s_was_prepared before +* enable/disable BCLK in trigger events because: +* 1. These trigger events are paired, so the BCLK +* enable_count is balanced. +* 2. the BCLK can be shared (ex: headset and headset mic), +* we need to increase the enable_count so that we don't +* turn off the shared BCLK while other devices are using +* it. +*/ if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) { ret =regmap_fields_write (i2sctl->spken, id,LPAIF_I2SCTL_SPKEN_ENABLE );
@@ -296,6 +330,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,case SNDRV_PCM_TRIGGER_STOP :case SNDRV_PCM_TRIGGER_SUSPEND :case SNDRV_PCM_TRIGGER_PAUSE_PUSH : +/* +* To ensure lpass BCLK/LRCLK is disabled during +* device suspend. +*/ if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) { ret =regmap_fields_write (i2sctl->spken, id,LPAIF_I2SCTL_SPKEN_DISABLE );
@@ -315,12 +353,53 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,return ret; } +static int lpass_cpu_daiops_prepare (struct snd_pcm_substream *substream, +struct snd_soc_dai *dai) +{ +struct lpass_data *drvdata =snd_soc_dai_get_drvdata (dai); +struct lpaif_i2sctl *i2sctl = drvdata->i2sctl; +unsigned int id = dai->driver->id; +int ret; + +/* +* Ensure lpass BCLK/LRCLK is enabled bit before playback/capture +* data flow starts. This allows other codec to have some delay before +* the data flow. +* (ex: to drop start up pop noise before capture starts). +*/ +if (substream->stream ==SNDRV_PCM_STREAM_PLAYBACK ) + ret =regmap_fields_write (i2sctl->spken, id,LPAIF_I2SCTL_SPKEN_ENABLE ); +else + ret =regmap_fields_write (i2sctl->micen, id,LPAIF_I2SCTL_MICEN_ENABLE ); + +if (ret) { +dev_err (dai->dev,"error writing to i2sctl reg: %d\n" , ret); +return ret; + } + +/* +* Check mi2s_was_prepared before enabling BCLK as lpass_cpu_daiops_prepare can +* be called multiple times. It's paired with the clk_disable in +* lpass_cpu_daiops_shutdown. +*/ +if (!drvdata->mi2s_was_prepared[dai->driver->id]) { + ret =clk_enable (drvdata->mi2s_bit_clk[id]); +if (ret) { +dev_err (dai->dev,"error in enabling mi2s bit clk: %d\n" , ret); +return ret; + } + drvdata->mi2s_was_prepared[dai->driver->id] = true; + } +return 0 ; +} +const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = { .set_sysclk = lpass_cpu_daiops_set_sysclk, .startup = lpass_cpu_daiops_startup, .shutdown = lpass_cpu_daiops_shutdown, .hw_params = lpass_cpu_daiops_hw_params, .trigger = lpass_cpu_daiops_trigger, + .prepare = lpass_cpu_daiops_prepare, };EXPORT_SYMBOL_GPL (asoc_qcom_lpass_cpu_dai_ops);
sound/soc/qcom/lpass.h +4 -0
@@ -67,6 +67,10 @@ struct lpass_data {/* MI2S SD lines to use for playback/capture */ unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS ];unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS ]; + +/* The state of MI2S prepare dai_ops was called */ +bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS ]; +int hdmi_port_enable;/* low-power audio interface (LPAIF) registers */
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 107/178 radeon: use memcpy_to/fromio for UVD fw upload
In reply to Greg Kroah-HartmanFrom: Chen Li <[email protected]>
[ Upstream commit ab8363d3875a83f4901eb1cc00ce8afd24de6c85 ]
I met a gpu addr bug recently and the kernel log tells me the pc is memcpy/memset and link register is radeon_uvd_resume.
As we know, in some architectures, optimized memcpy/memset may not work well on device memory. Trival memcpy_toio/memset_io can fix this problem.
BTW, amdgpu has already done it in:
commit ba0b2275a678 ("drm/amdgpu: use memcpy_to/fromio for UVD fw upload"), that's why it has no this issue on the same gpu and platform.
--- drivers/gpu/drm/radeon/radeon_uvd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/radeon_uvd.c +2 -2
@@ -286,7 +286,7 @@ int radeon_uvd_resume(struct radeon_device *rdev)if (rdev->uvd.vcpu_bo ==NULL )return -EINVAL ; -memcpy (rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); +memcpy_toio ((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); size =radeon_bo_size (rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size;
@@ -294,7 +294,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size; -memset (ptr,0 , size); +memset_io ((void __iomem *)ptr,0 , size);return 0 ; }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 108/178 hwmon: (scpi-hwmon) shows the negative temperature properly
In reply to Greg Kroah-HartmanFrom: Riwen Lu <[email protected]>
[ Upstream commit 78d13552346289bad4a9bf8eabb5eec5e5a321a5 ]
The scpi hwmon shows the sub-zero temperature in an unsigned integer, which would confuse the users when the machine works in low temperature environment. This shows the sub-zero temperature in an signed value and users can get it properly from sensors.
--- drivers/hwmon/scpi-hwmon.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/hwmon/scpi-hwmon.c +9 -0
@@ -99,6 +99,15 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf)scpi_scale_reading (&value, sensor); +/* +* Temperature sensor values are treated as signed values based on +* observation even though that is not explicitly specified, and +* because an unsigned u64 temperature does not really make practical +* sense especially when the temperature is below zero degrees Celsius. +*/ +if (sensor->info.class ==TEMPERATURE ) +return sprintf (buf,"%lld\n" , (s64 )value); +return sprintf (buf,"%llu\n" , value); }
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 109/178 riscv: code patching only works on !XIP_KERNEL
In reply to Greg Kroah-HartmanFrom: Jisheng Zhang <[email protected]>
[ Upstream commit 42e0e0b453bc6ead49c573ed512502069627546b ]
Some features which need code patching such as KPROBES, DYNAMIC_FTRACE KGDB can only work on !XIP_KERNEL. Add dependencies for these features that rely on code patching.
--- arch/riscv/Kconfig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
arch/riscv/Kconfig +9 -9
@@ -54,11 +54,11 @@ config RISCV select GENERIC_TIME_VSYSCALL if MMU && 64BIT select HANDLE_DOMAIN_IRQ select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_JUMP_LABEL - select HAVE_ARCH_JUMP_LABEL_RELATIVE + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL + select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL select HAVE_ARCH_KASAN if MMU && 64BIT select HAVE_ARCH_KASAN_VMALLOC if MMU && 64BIT - select HAVE_ARCH_KGDB + select HAVE_ARCH_KGDB if !XIP_KERNEL select HAVE_ARCH_KGDB_QXFER_PKT select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_SECCOMP_FILTER
@@ -73,9 +73,9 @@ config RISCV select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO if MMU && 64BIT select HAVE_IRQ_TIME_ACCOUNTING - select HAVE_KPROBES - select HAVE_KPROBES_ON_FTRACE - select HAVE_KRETPROBES + select HAVE_KPROBES if !XIP_KERNEL + select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL + select HAVE_KRETPROBES if !XIP_KERNEL select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS
@@ -227,11 +227,11 @@ config ARCH_RV64I bool "RV64I" select 64BIT select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && GCC_VERSION >= 50000 - select HAVE_DYNAMIC_FTRACE if MMU && $(cc-option,-fpatchable-function-entry=8) + select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && $(cc-option,-fpatchable-function-entry=8) select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER - select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACER if !XIP_KERNEL select SWIOTLB if MMU endchoice
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 110/178 mm: relocate write_protect_seq in struct mm_struct
In reply to Greg Kroah-HartmanFrom: Feng Tang <[email protected]>
[ Upstream commit 2e3025434a6ba090c85871a1d4080ff784109e1f ]
0day robot reported a 9.2% regression for will-it-scale mmap1 test case[1], caused by commit 57efa1fe5957 ("mm/gup: prevent gup_fast from racing with COW during fork").
Further debug shows the regression is due to that commit changes the offset of hot fields 'mmap_lock' inside structure 'mm_struct', thus some cache alignment changes.
Quoted 1 line
From the perf data, the contention for '
mmap_lock' is very severe and
takes around 95% cpu cycles, and it is a rw_semaphore
struct rw_semaphore {
atomic_long_t count; /* 8 bytes */
atomic_long_t owner; /* 8 bytes */
struct optimistic_spin_queue osq; /* spinner MCS lock */
...Before commit 57efa1fe5957 adds the 'write_protect_seq', it happens to have a very optimal cache alignment layout, as Linus explained:
"and before the addition of the 'write_protect_seq' field, the
mmap_sem was at offset 120 in 'struct mm_struct'.
Which meant that count and owner were in two different cachelines, and then when you have contention and spend time in rwsem_down_write_slowpath(), this is probably *exactly* the kind of layout you want.
Because first the rwsem_write_trylock() will do a cmpxchg on the first cacheline (for the optimistic fast-path), and then in the case of contention, rwsem_down_write_slowpath() will just access the second cacheline.
Which is probably just optimal for a load that spends a lot of time contended - new waiters touch that first cacheline, and then they queue themselves up on the second cacheline."
After the commit, the rw_semaphore is at offset 128, which means the 'count' and 'owner' fields are now in the same cacheline, and causes more cache bouncing.
Currently there are 3 "#ifdef CONFIG_XXX" before 'mmap_lock' which will affect its offset:
CONFIG_MMU
CONFIG_MEMBARRIER
CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES
The layout above is on 64 bits system with 0day's default kernel config (similar to RHEL-8.3's config), in which all these 3 options are 'y'. And the layout can vary with different kernel configs.
Relayouting a structure is usually a double-edged sword, as sometimes it can helps one case, but hurt other cases. For this case, one solution is, as the newly added 'write_protect_seq' is a 4 bytes long seqcount_t (when CONFIG_DEBUG_LOCK_ALLOC=n), placing it into an existing 4 bytes hole in 'mm_struct' will not change other fields' alignment, while restoring the regression.
--- include/linux/mm_types.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
include/linux/mm_types.h +20 -7
@@ -445,13 +445,6 @@ struct mm_struct {*/ atomic_t has_pinned; -/** -* @write_protect_seq: Locked when any thread is write -* protecting pages mapped by this mm to enforce a later COW, -* for instance during page table copying for fork(). -*/ -seqcount_t write_protect_seq; -#ifdef CONFIG_MMU atomic_long_t pgtables_bytes;/* PTE page table pages */ #endif
@@ -460,6 +453,18 @@ struct mm_struct {spinlock_t page_table_lock;/* Protects page tables and some * counters */ +/* +* With some kernel config, the current mmap_lock's offset +* inside 'mm_struct' is at 0x120, which is very optimal, as +* its two hot fields 'count' and 'owner' sit in 2 different +* cachelines, and when mmap_lock is highly contended, both +* of the 2 fields will be accessed frequently, current layout +* will help to reduce cache bouncing. +* +* So please be careful with adding new fields before +* mmap_lock, which can easily push the 2 fields into one +* cacheline. +*/ struct rw_semaphore mmap_lock;struct list_head mmlist;/* List of maybe swapped mm's. These
@@ -480,7 +485,15 @@ struct mm_struct {unsigned long stack_vm;/* VM_STACK */ unsigned long def_flags; +/** +* @write_protect_seq: Locked when any thread is write +* protecting pages mapped by this mm to enforce a later COW, +* for instance during page table copying for fork(). +*/ +seqcount_t write_protect_seq; +spinlock_t arg_lock;/* protect the below fields */ +unsigned long start_code, end_code, start_data, end_data;unsigned long start_brk, brk, start_stack;unsigned long arg_start, arg_end, env_start, env_end;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 111/178 irqchip/gic-v3: Workaround inconsistent PMR setting on NMI entry
In reply to Greg Kroah-HartmanFrom: Marc Zyngier <[email protected]>
[ Upstream commit 382e6e177bc1c02473e56591fe5083ae1e4904f6 ]
The arm64 entry code suffers from an annoying issue on taking a NMI, as it sets PMR to a value that actually allows IRQs to be acknowledged. This is done for consistency with other parts of the code, and is in the process of being fixed. This shouldn't be a problem, as we are not enabling interrupts whilst in NMI context.
However, in the infortunate scenario that we took a spurious NMI (retired before the read of IAR) *and* that there is an IRQ pending at the same time, we'll ack the IRQ in NMI context. Too bad.
In order to avoid deadlocks while running something like perf, teach the GICv3 driver about this situation: if we were in a context where no interrupt should have fired, transiently set PMR to a value that only allows NMIs before acking the pending interrupt, and restore the original value after that.
This papers over the core issue for the time being, and makes NMIs great again. Sort of.
--- drivers/irqchip/irq-gic-v3.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-)
drivers/irqchip/irq-gic-v3.c +35 -1
@@ -642,11 +642,45 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)nmi_exit (); } +static u32 do_read_iar (struct pt_regs *regs) +{ +u32 iar; + +if (gic_supports_nmi () &&unlikely (!interrupts_enabled (regs))) { +u64 pmr; + +/* +* We were in a context with IRQs disabled. However, the +* entry code has set PMR to a value that allows any +* interrupt to be acknowledged, and not just NMIs. This can +* lead to surprising effects if the NMI has been retired in +* the meantime, and that there is an IRQ pending. The IRQ +* would then be taken in NMI context, something that nobody +* wants to debug twice. +* +* Until we sort this, drop PMR again to a level that will +* actually only allow NMIs before reading IAR, and then +* restore it to what it was. +*/ + pmr =gic_read_pmr (); +gic_pmr_mask_irqs (); +isb (); + + iar =gic_read_iar (); + +gic_write_pmr (pmr); + }else { + iar =gic_read_iar (); + } + +return iar; +} + static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) {u32 irqnr; - irqnr =gic_read_iar (); + irqnr =do_read_iar (regs);/* Check for special IDs first */ if ((irqnr >=1020 && irqnr <=1023 ))
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 112/178 sched/fair: Correctly insert cfs_rqs to list on unthrottle
In reply to Greg Kroah-HartmanFrom: Odin Ugedal <[email protected]>
[ Upstream commit a7b359fc6a37faaf472125867c8dc5a068c90982 ]
Fix an issue where fairness is decreased since cfs_rq's can end up not being decayed properly. For two sibling control groups with the same priority, this can often lead to a load ratio of 99/1 (!!).
This happens because when a cfs_rq is throttled, all the descendant cfs_rq's will be removed from the leaf list. When they initial cfs_rq is unthrottled, it will currently only re add descendant cfs_rq's if they have one or more entities enqueued. This is not a perfect heuristic.
Instead, we insert all cfs_rq's that contain one or more enqueued entities, or it its load is not completely decayed.
Can often lead to situations like this for equally weighted control groups:
$ ps u -C stress USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 10009 88.8 0.0 3676 100 pts/1 R+ 11:04 0:13 stress --cpu 1 root 10023 3.0 0.0 3676 104 pts/1 R+ 11:04 0:00 stress --cpu 1
--- kernel/sched/fair.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-)
kernel/sched/fair.c +25 -19
@@ -3293,6 +3293,24 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq, int flags)#ifdef CONFIG_SMP #ifdef CONFIG_FAIR_GROUP_SCHED + +static inline bool cfs_rq_is_decayed (struct cfs_rq *cfs_rq) +{ +if (cfs_rq->load.weight) +return false; + +if (cfs_rq->avg.load_sum) +return false; + +if (cfs_rq->avg.util_sum) +return false; + +if (cfs_rq->avg.runnable_sum) +return false; + +return true; +} +/** * update_tg_load_avg - update the tg's load avg * @cfs_rq: the cfs_rq whose avg changed
@@ -4086,6 +4104,11 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)#else /* CONFIG_SMP */ +static inline bool cfs_rq_is_decayed (struct cfs_rq *cfs_rq) +{ +return true; +} +#define UPDATE_TG 0x0#define SKIP_AGE_LOAD 0x0#define DO_ATTACH 0x0
@@ -4744,8 +4767,8 @@ static int tg_unthrottle_up(struct task_group *tg, void *data) cfs_rq->throttled_clock_task_time +=rq_clock_task (rq) - cfs_rq->throttled_clock_task; -/* Add cfs_rq with already running entity in the list */ -if (cfs_rq->nr_running >=1 ) +/* Add cfs_rq with load or one or more already running entities to the list */ +if (!cfs_rq_is_decayed (cfs_rq) || cfs_rq->nr_running)list_add_leaf_cfs_rq (cfs_rq); }
@@ -7972,23 +7995,6 @@ static bool __update_blocked_others(struct rq *rq, bool *done)#ifdef CONFIG_FAIR_GROUP_SCHED -static inline bool cfs_rq_is_decayed (struct cfs_rq *cfs_rq) -{ -if (cfs_rq->load.weight) -return false; - -if (cfs_rq->avg.load_sum) -return false; - -if (cfs_rq->avg.util_sum) -return false; - -if (cfs_rq->avg.runnable_sum) -return false; - -return true; -} -static bool __update_blocked_fair (struct rq *rq,bool *done) {struct cfs_rq *cfs_rq, *pos;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 113/178 perf metricgroup: Fix find_evsel_group() event selector
In reply to Greg Kroah-HartmanFrom: John Garry <[email protected]>
[ Upstream commit fc96ec4d5d4155c61cbafd49fb2dd403c899a9f4 ]
The following command segfaults on my x86 broadwell:
$ ./perf stat -M frontend_bound,retiring,backend_bound,bad_speculation sleep 1
WARNING: grouped events cpus do not match, disabling group:
anon group { raw 0x10e }
anon group { raw 0x10e }
perf: util/evsel.c:1596: get_group_fd: Assertion `!(!leader->core.fd)' failed.
Aborted (core dumped)The issue shows itself as a use-after-free in evlist__check_cpu_maps(), whereby the leader of an event selector (evsel) has been deleted (yet we still attempt to verify for an evsel).
Fundamentally the problem comes from metricgroup__setup_events() -> find_evsel_group(), and has developed from the previous fix attempt in commit 9c880c24cb0d ("perf metricgroup: Fix for metrics containing duration_time").
The problem now is that the logic in checking if an evsel is in the same group is subtly broken for the "cycles" event. For the "cycles" event, the pmu_name is NULL; however the logic in find_evsel_group() may set an event matched against "cycles" as used, when it should not be.
This leads to a condition where an evsel is set, yet its leader is not.
Fix the check for evsel pmu_name by not matching evsels when either has a NULL pmu_name.
There is still a pre-existing metric issue whereby the ordering of the metrics may break the 'stat' function, as discussed at:
https://lore.kernel.org/lkml/[email protected]/
--- tools/perf/util/metricgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/metricgroup.c +3 -3
@@ -162,10 +162,10 @@ static bool contains_event(struct evsel **metric_events, int num_events,return false; } -static bool evsel_same_pmu (struct evsel *ev1,struct evsel *ev2) +static bool evsel_same_pmu_or_none (struct evsel *ev1,struct evsel *ev2) {if (!ev1->pmu_name || !ev2->pmu_name) -return false; +return true;return !strcmp (ev1->pmu_name, ev2->pmu_name); }
@@ -288,7 +288,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist,*/ if (!has_constraint && ev->leader != metric_events[i]->leader && -evsel_same_pmu (ev->leader, metric_events[i]->leader)) +evsel_same_pmu_or_none (ev->leader, metric_events[i]->leader))break ;if (!strcmp (metric_events[i]->name, ev->name)) {set_bit (ev->idx, evlist_used);
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 114/178 perf metricgroup: Return error code from metricgroup__add_metric_sys_event_iter()
In reply to Greg Kroah-HartmanFrom: John Garry <[email protected]>
[ Upstream commit fe7a98b9d9b36e5c8a22d76b67d29721f153f66e ]
The error code is not set at all in the sys event iter function.
This may lead to an uninitialized value of "ret" in metricgroup__add_metric() when no CPU metric is added.
Fix by properly setting the error code.
It is not necessary to init "ret" to 0 in metricgroup__add_metric(), as if we have no CPU or sys event metric matching, then "has_match" should be 0 and "ret" is set to -EINVAL.
However gcc cannot detect that it may not have been set after the map_for_each_metric() loop for CPU metrics, which is strange.
--- tools/perf/util/metricgroup.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
tools/perf/util/metricgroup.c +5 -3
@@ -1072,16 +1072,18 @@ static int metricgroup__add_metric_sys_event_iter(struct pmu_event *pe, ret =add_metric (d->metric_list, pe, d->metric_no_group, &m,NULL , d->ids);if (ret) -return ret; + goto out; ret =resolve_metric (d->metric_no_group, d->metric_list,NULL , d->ids);if (ret) -return ret; + goto out; *(d->has_match) = true; -return *d->ret; +out: + *(d->ret) = ret; +return ret; } static int metricgroup__add_metric(const char *metric, bool metric_no_group,
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 115/178 bpf: Inherit expanded/patched seen count from old aux data
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
[ Upstream commit d203b0fd863a2261e5d00b97f3d060c4c2a6db71 ]
Instead of relying on current env->pass_cnt, use the seen count from the old aux data in adjust_insn_aux_data(), and expand it to the new range of patched instructions. This change is valid given we always expand 1:n with n>=1, so what applies to the old/original instruction needs to apply for the replacement as well.
Not relying on env->pass_cnt is a prerequisite for a later change where we want to avoid marking an instruction seen when verified under speculative execution path.
--- kernel/bpf/verifier.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +3 -1
@@ -10820,6 +10820,7 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env, {struct bpf_insn_aux_data *new_data, *old_data = env->insn_aux_data;struct bpf_insn *insn = new_prog->insnsi; +u32 old_seen = old_data[off].seen;u32 prog_len;int i;
@@ -10840,7 +10841,8 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env,memcpy (new_data + off + cnt -1 , old_data + off,sizeof (struct bpf_insn_aux_data ) * (prog_len - off - cnt +1 ));for (i = off; i < off + cnt -1 ; i++) { - new_data[i].seen = env->pass_cnt; +/* Expand insni[off]'s seen count to the patched range. */ + new_data[i].seen = old_seen; new_data[i].zext_dst =insn_has_def32 (env, insn + i); } env->insn_aux_data = new_data;
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 116/178 bpf: Do not mark insn as seen under speculative path verification
In reply to Greg Kroah-HartmanFrom: Daniel Borkmann <[email protected]>
[ Upstream commit fe9a5ca7e370e613a9a75a13008a3845ea759d6e ]
... in such circumstances, we do not want to mark the instruction as seen given the goal is still to jmp-1 rewrite/sanitize dead code, if it is not reachable from the non-speculative path verification. We do however want to verify it for safety regardless.
With the patch as-is all the insns that have been marked as seen before the patch will also be marked as seen after the patch (just with a potentially different non-zero count). An upcoming patch will also verify paths that are unreachable in the non-speculative domain, hence this extension is needed.
--- kernel/bpf/verifier.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
kernel/bpf/verifier.c +18 -2
@@ -6048,6 +6048,19 @@ do_sim:return !ret ?REASON_STACK :0 ; } +static void sanitize_mark_insn_seen (struct bpf_verifier_env *env) +{ +struct bpf_verifier_state *vstate = env->cur_state; + +/* If we simulate paths under speculation, we don't update the +* insn as 'seen' such that when we verify unreachable paths in +* the non-speculative domain, sanitize_dead_code() can still +* rewrite/sanitize them. +*/ +if (!vstate->speculative) + env->insn_aux_data[env->insn_idx].seen = env->pass_cnt; +} + static int sanitize_err(struct bpf_verifier_env *env, const struct bpf_insn *insn, int reason, const struct bpf_reg_state *off_reg,
@@ -10096,7 +10109,7 @@ static int do_check(struct bpf_verifier_env *env) } regs =cur_regs (env); - env->insn_aux_data[env->insn_idx].seen = env->pass_cnt; +sanitize_mark_insn_seen (env); prev_insn_idx = env->insn_idx;if (class ==BPF_ALU || class ==BPF_ALU64 ) {
@@ -10321,7 +10334,7 @@ process_bpf_exit:return err; env->insn_idx++; - env->insn_aux_data[env->insn_idx].seen = env->pass_cnt; +sanitize_mark_insn_seen (env); }else {verbose (env,"invalid BPF_LD mode\n" );return -EINVAL ;
@@ -12098,6 +12111,9 @@ static void free_states(struct bpf_verifier_env *env)* insn_aux_data was touched. These variables are compared to clear temporary * data from failed pass. For testing and experiments do_check_common() can be * run multiple times even when prior attempt to verify is unsuccessful. +* +* Note that special handling is needed on !env->bypass_spec_v1 if this is +* ever called outside of error path with subsequent program rejection. */ static void sanitize_insn_aux_data (struct bpf_verifier_env *env) {
Signature · 1 line
2.30.2
Greg Kroah-Hartman
maintainerPATCH 117/178 can: bcm: fix infoleak in struct bcm_msg_head
In reply to Greg Kroah-HartmanFrom: Norbert Slusarek <[email protected]>
commit 5e87ddbe3942e27e939bdc02deb8579b0cbd8ecc upstream.
On 64-bit systems, struct bcm_msg_head has an added padding of 4 bytes between struct members count and ival1. Even though all struct members are initialized, the 4-byte hole will contain data from the kernel stack. This patch zeroes out struct bcm_msg_head before usage, preventing infoleaks to userspace.
--- net/can/bcm.c | 3 +++ 1 file changed, 3 insertions(+)
net/can/bcm.c +3 -0
@@ -402,6 +402,7 @@ static enum hrtimer_restart bcm_tx_timeoif (!op->count && (op->flags &TX_COUNTEVT )) {/* create notification to user */ +memset (&msg_head,0 ,sizeof (msg_head)); msg_head.opcode =TX_EXPIRED ; msg_head.flags = op->flags; msg_head.count = op->count;
@@ -439,6 +440,7 @@ static void bcm_rx_changed(struct bcm_op/* this element is not throttled anymore */ data->flags &= (BCM_CAN_FLAGS_MASK |RX_RECV ); +memset (&head,0 ,sizeof (head)); head.opcode =RX_CHANGED ; head.flags = op->flags; head.count = op->count;
@@ -560,6 +562,7 @@ static enum hrtimer_restart bcm_rx_timeo }/* create notification to user */ +memset (&msg_head,0 ,sizeof (msg_head)); msg_head.opcode =RX_TIMEOUT ; msg_head.flags = op->flags; msg_head.count = op->count;
Greg Kroah-Hartman
maintainerPATCH 118/178 can: bcm/raw/isotp: use per module netdevice notifier
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
commit 8d0caedb759683041d9db82069937525999ada53 upstream.
syzbot is reporting hung task at register_netdevice_notifier() [1] and unregister_netdevice_notifier() [2], for cleanup_net() might perform time consuming operations while CAN driver's raw/bcm/isotp modules are calling {register,unregister}_netdevice_notifier() on each socket.
Change raw/bcm/isotp modules to call register_netdevice_notifier() from module's __init function and call unregister_netdevice_notifier() from module's __exit function, as with gw/j1939 modules are doing.
--- net/can/bcm.c | 59 +++++++++++++++++++++++++++++++++++++++++------------ net/can/isotp.c | 61 +++++++++++++++++++++++++++++++++++++++++++------------ net/can/raw.c | 62 +++++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 142 insertions(+), 40 deletions(-)
net/can/bcm.c +46 -13
@@ -125,7 +125,7 @@ struct bcm_sock {struct sock sk;int bound;int ifindex; -struct notifier_block notifier; +struct list_head notifier;struct list_head rx_ops;struct list_head tx_ops;unsigned long dropped_usr_msgs;
@@ -133,6 +133,10 @@ struct bcm_sock {char procname [32 ];/* inode number in decimal with \0 */ }; +static LIST_HEAD (bcm_notifier_list); +static DEFINE_SPINLOCK (bcm_notifier_lock); +static struct bcm_sock *bcm_busy_notifier; +static inline struct bcm_sock *bcm_sk (const struct sock *sk) {return (struct bcm_sock *)sk;
@@ -1381,20 +1385,15 @@ static int bcm_sendmsg(struct socket *so/* * notification handler for netdevice status changes */ -static int bcm_notifier (struct notifier_block *nb,unsigned long msg, -void *ptr) +static void bcm_notify (struct bcm_sock *bo,unsigned long msg, +struct net_device *dev) { -struct net_device *dev =netdev_notifier_info_to_dev (ptr); - struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);struct sock *sk = &bo->sk;struct bcm_op *op;int notify_enodev =0 ;if (!net_eq (dev_net (dev),sock_net (sk))) -return NOTIFY_DONE ; - -if (dev->type !=ARPHRD_CAN ) -return NOTIFY_DONE ; +return ;switch (msg) {
@@ -1429,7 +1428,28 @@ static int bcm_notifier(struct notifier_ sk->sk_error_report (sk); } } +} +static int bcm_notifier (struct notifier_block *nb,unsigned long msg, +void *ptr) +{ +struct net_device *dev =netdev_notifier_info_to_dev (ptr); + +if (dev->type !=ARPHRD_CAN ) +return NOTIFY_DONE ; +if (msg !=NETDEV_UNREGISTER && msg !=NETDEV_DOWN ) +return NOTIFY_DONE ; +if (unlikely (bcm_busy_notifier))/* Check for reentrant bug. */ +return NOTIFY_DONE ; + +spin_lock (&bcm_notifier_lock); +list_for_each_entry (bcm_busy_notifier, &bcm_notifier_list, notifier) { +spin_unlock (&bcm_notifier_lock); +bcm_notify (bcm_busy_notifier, msg, dev); +spin_lock (&bcm_notifier_lock); + } + bcm_busy_notifier =NULL ; +spin_unlock (&bcm_notifier_lock);return NOTIFY_DONE ; }
@@ -1449,9 +1469,9 @@ static int bcm_init(struct sock *sk)INIT_LIST_HEAD (&bo->rx_ops);/* set notifier */ - bo->notifier.notifier_call = bcm_notifier; - -register_netdevice_notifier (&bo->notifier); +spin_lock (&bcm_notifier_lock); +list_add_tail (&bo->notifier, &bcm_notifier_list); +spin_unlock (&bcm_notifier_lock);return 0 ; }
@@ -1474,7 +1494,14 @@ static int bcm_release(struct socket *so/* remove bcm_ops, timer, rx_unregister(), etc. */ -unregister_netdevice_notifier (&bo->notifier); +spin_lock (&bcm_notifier_lock); +while (bcm_busy_notifier == bo) { +spin_unlock (&bcm_notifier_lock); +schedule_timeout_uninterruptible (1 ); +spin_lock (&bcm_notifier_lock); + } +list_del (&bo->notifier); +spin_unlock (&bcm_notifier_lock);lock_sock (sk);
@@ -1695,6 +1722,10 @@ static struct pernet_operations canbcm_p .exit = canbcm_pernet_exit, }; +static struct notifier_block canbcm_notifier = { + .notifier_call = bcm_notifier +}; +static int __init bcm_module_init (void ) {int err;
@@ -1708,12 +1739,14 @@ static int __init bcm_module_init(void) }register_pernet_subsys (&canbcm_pernet_ops); +register_netdevice_notifier (&canbcm_notifier);return 0 ; } static void __exit bcm_module_exit(void) {can_proto_unregister (&bcm_can_proto); +unregister_netdevice_notifier (&canbcm_notifier);unregister_pernet_subsys (&canbcm_pernet_ops); }
net/can/isotp.c +48 -13
119 lines not on this page · raw message
net/can/raw.c +48 -14
123 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 119/178 can: j1939: fix Use-after-Free, hold skb ref while in use
In reply to Greg Kroah-HartmanFrom: Oleksij Rempel <[email protected]>
commit 2030043e616cab40f510299f09b636285e0a3678 upstream.
This patch fixes a Use-after-Free found by the syzbot.
The problem is that a skb is taken from the per-session skb queue, without incrementing the ref count. This leads to a Use-after-Free if the skb is taken concurrently from the session queue due to a CTS.
--- net/can/j1939/transport.c | 54 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-)
net/can/j1939/transport.c +40 -14
@@ -330,6 +330,9 @@ static void j1939_session_skb_drop_old(sif ((do_skcb->offset + do_skb->len) < offset_start) {__skb_unlink (do_skb, &session->skb_queue); +/* drop ref taken in j1939_session_skb_queue() */ +skb_unref (do_skb); +kfree_skb (do_skb); }spin_unlock_irqrestore (&session->skb_queue.lock, flags);
@@ -349,12 +352,13 @@ void j1939_session_skb_queue(struct j193 skcb->flags |=J1939_ECU_LOCAL_SRC ; +skb_get (skb);skb_queue_tail (&session->skb_queue, skb); }static struct -sk_buff *j1939_session_skb_find_by_offset (struct j1939_session *session, -unsigned int offset_start) +sk_buff *j1939_session_skb_get_by_offset (struct j1939_session *session, +unsigned int offset_start) {struct j1939_priv *priv = session->priv;struct j1939_sk_buff_cb *do_skcb;
@@ -371,6 +375,10 @@ sk_buff *j1939_session_skb_find_by_offse skb = do_skb; } } + +if (skb) +skb_get (skb); +spin_unlock_irqrestore (&session->skb_queue.lock, flags);if (!skb)
@@ -381,12 +389,12 @@ sk_buff *j1939_session_skb_find_by_offsereturn skb; } -static struct sk_buff *j1939_session_skb_find (struct j1939_session *session) +static struct sk_buff *j1939_session_skb_get (struct j1939_session *session) {unsigned int offset_start; offset_start = session->pkt.dpo *7 ; -return j1939_session_skb_find_by_offset (session, offset_start); +return j1939_session_skb_get_by_offset (session, offset_start); }/* see if we are receiver
@@ -776,7 +784,7 @@ static int j1939_session_tx_dat(struct jint ret =0 ;u8 dat[8 ]; - se_skb =j1939_session_skb_find_by_offset (session, session->pkt.tx *7 ); + se_skb =j1939_session_skb_get_by_offset (session, session->pkt.tx *7 );if (!se_skb)return -ENOBUFS ;
@@ -801,7 +809,8 @@ static int j1939_session_tx_dat(struct jnetdev_err_once (priv->ndev,"%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n" , __func__, session, skcb->offset, se_skb->len , session->pkt.tx); -return -EOVERFLOW ; + ret = -EOVERFLOW ; + goto out_free; }if (!len) {
@@ -835,6 +844,12 @@ static int j1939_session_tx_dat(struct jif (pkt_done)j1939_tp_set_rxtimeout (session,250 ); + out_free: +if (ret) +kfree_skb (se_skb); +else +consume_skb (se_skb); +return ret; }
@@ -1007,7 +1022,7 @@ static int j1939_xtp_txnext_receiver(strstatic int j1939_simple_txnext (struct j1939_session *session) {struct j1939_priv *priv = session->priv; -struct sk_buff *se_skb =j1939_session_skb_find (session); +struct sk_buff *se_skb =j1939_session_skb_get (session);struct sk_buff *skb;int ret;
@@ -1015,8 +1030,10 @@ static int j1939_simple_txnext(struct j1return 0 ; skb =skb_clone (se_skb,GFP_ATOMIC ); -if (!skb) -return -ENOMEM ; +if (!skb) { + ret = -ENOMEM ; + goto out_free; + }can_skb_set_owner (skb, se_skb->sk);
@@ -1024,12 +1041,18 @@ static int j1939_simple_txnext(struct j1 ret =j1939_send_one (priv, skb);if (ret) -return ret; + goto out_free;j1939_sk_errqueue (session,J1939_ERRQUEUE_SCHED );j1939_sk_queue_activate_next (session); -return 0 ; + out_free: +if (ret) +kfree_skb (se_skb); +else +consume_skb (se_skb); + +return ret; }static bool j1939_session_deactivate_locked (struct j1939_session *session)
@@ -1170,9 +1193,10 @@ static void j1939_session_completed(strustruct sk_buff *skb;if (!session->transmission) { - skb =j1939_session_skb_find (session); + skb =j1939_session_skb_get (session);/* distribute among j1939 receivers */ j1939_sk_recv (session->priv, skb); +consume_skb (skb); }j1939_session_deactivate_activate_next (session);
@@ -1744,7 +1768,7 @@ static void j1939_xtp_rx_dat_one(struct {struct j1939_priv *priv = session->priv;struct j1939_sk_buff_cb *skcb; -struct sk_buff *se_skb; +struct sk_buff *se_skb =NULL ;const u8 *dat;u8 *tpdat;int offset;
@@ -1786,7 +1810,7 @@ static void j1939_xtp_rx_dat_one(struct goto out_session_cancel; } - se_skb =j1939_session_skb_find_by_offset (session, packet *7 ); + se_skb =j1939_session_skb_get_by_offset (session, packet *7 );if (!se_skb) {netdev_warn (priv->ndev,"%s: 0x%p: no skb found\n" , __func__, session);
@@ -1848,11 +1872,13 @@ static void j1939_xtp_rx_dat_one(structj1939_tp_set_rxtimeout (session,250 ); } session->last_cmd =0xff ; +consume_skb (se_skb);j1939_session_put (session);return ; out_session_cancel: +kfree_skb (se_skb);j1939_session_timers_cancel (session);j1939_session_cancel (session,J1939_XTP_ABORT_FAULT );j1939_session_put (session);
Greg Kroah-Hartman
maintainerPATCH 120/178 can: mcba_usb: fix memory leak in mcba_usb
In reply to Greg Kroah-HartmanFrom: Pavel Skripkin <[email protected]>
commit 91c02557174be7f72e46ed7311e3bea1939840b0 upstream.
Syzbot reported memory leak in SocketCAN driver for Microchip CAN BUS Analyzer Tool. The problem was in unfreed usb_coherent.
In mcba_usb_start() 20 coherent buffers are allocated and there is nothing, that frees them:
1) In callback function the urb is resubmitted and that's all
2) In disconnect function urbs are simply killed, but URB_FREE_BUFFER is not set (see mcba_usb_start) and this flag cannot be used with coherent buffers.
Fail log:
| [ 1354.053291][ T8413] mcba_usb 1-1:0.0 can0: device disconnected
| [ 1367.059384][ T8420] kmemleak: 20 new suspected memory leaks (see /sys/kernel/debug/kmem)
So, all allocated buffers should be freed with usb_free_coherent() explicitly
NOTE:
The same pattern for allocating and freeing coherent buffers is used in drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
--- drivers/net/can/usb/mcba_usb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/net/can/usb/mcba_usb.c +15 -2
@@ -82,6 +82,8 @@ struct mcba_priv {bool can_ka_first_pass;bool can_speed_check;atomic_t free_ctx_cnt; +void *rxbuf[MCBA_MAX_RX_URBS ]; +dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS ]; };/* CAN frame */
@@ -633,6 +635,7 @@ static int mcba_usb_start(struct mcba_prfor (i =0 ; i <MCBA_MAX_RX_URBS ; i++) {struct urb *urb =NULL ;u8 *buf; +dma_addr_t buf_dma;/* create a URB, and a buffer for it */ urb =usb_alloc_urb (0 ,GFP_KERNEL );
@@ -642,7 +645,7 @@ static int mcba_usb_start(struct mcba_pr } buf =usb_alloc_coherent (priv->udev,MCBA_USB_RX_BUFF_SIZE , -GFP_KERNEL , &urb->transfer_dma); +GFP_KERNEL , &buf_dma);if (!buf) {netdev_err (netdev,"No memory left for USB buffer\n" );usb_free_urb (urb);
@@ -661,11 +664,14 @@ static int mcba_usb_start(struct mcba_prif (err) {usb_unanchor_urb (urb);usb_free_coherent (priv->udev,MCBA_USB_RX_BUFF_SIZE , - buf, urb->transfer_dma); + buf, buf_dma);usb_free_urb (urb);break ; } + priv->rxbuf[i] = buf; + priv->rxbuf_dma[i] = buf_dma; +/* Drop reference, USB core will take care of freeing it */ usb_free_urb (urb); }
@@ -708,7 +714,14 @@ static int mcba_usb_open(struct net_devistatic void mcba_urb_unlink (struct mcba_priv *priv) { +int i; +usb_kill_anchored_urbs (&priv->rx_submitted); + +for (i =0 ; i <MCBA_MAX_RX_URBS ; ++i) +usb_free_coherent (priv->udev,MCBA_USB_RX_BUFF_SIZE , + priv->rxbuf[i], priv->rxbuf_dma[i]); +usb_kill_anchored_urbs (&priv->tx_submitted); }
Greg Kroah-Hartman
maintainerPATCH 121/178 usb: core: hub: Disable autosuspend for Cypress CY7C65632
In reply to Greg Kroah-HartmanFrom: Andrew Lunn <[email protected]>
commit a7d8d1c7a7f73e780aa9ae74926ae5985b2f895f upstream.
The Cypress CY7C65632 appears to have an issue with auto suspend and detecting devices, not too dissimilar to the SMSC 5534B hub. It is easiest to reproduce by connecting multiple mass storage devices to the hub at the same time. On a Lenovo Yoga, around 1 in 3 attempts result in the devices not being detected. It is however possible to make them appear using lsusb -v.
Disabling autosuspend for this hub resolves the issue.
--- drivers/usb/core/hub.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/core/hub.c +7 -0
@@ -40,6 +40,8 @@#define USB_VENDOR_GENESYS_LOGIC 0x05e3#define USB_VENDOR_SMSC 0x0424#define USB_PRODUCT_USB5534B 0x5534 +#define USB_VENDOR_CYPRESS 0x04b4 +#define USB_PRODUCT_CY7C65632 0x6570#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02
@@ -5645,6 +5647,11 @@ static const struct usb_device_id hub_id .bInterfaceClass = USB_CLASS_HUB, .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_CYPRESS, + .idProduct = USB_PRODUCT_CY7C65632, + .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, .idVendor = USB_VENDOR_GENESYS_LOGIC, .bInterfaceClass = USB_CLASS_HUB,
Greg Kroah-Hartman
maintainerPATCH 122/178 usb: chipidea: imx: Fix Battery Charger 1.2 CDP detection
In reply to Greg Kroah-HartmanFrom: Breno Lima <[email protected]>
commit c6d580d96f140596d69220f60ce0cfbea4ee5c0f upstream.
i.MX8MM cannot detect certain CDP USB HUBs. usbmisc_imx.c driver is not following CDP timing requirements defined by USB BC 1.2 specification and section 3.2.4 Detection Timing CDP.
During Primary Detection the i.MX device should turn on VDP_SRC and IDM_SINK for a minimum of 40ms (TVDPSRC_ON). After a time of TVDPSRC_ON, the i.MX is allowed to check the status of the D- line. Current implementation is waiting between 1ms and 2ms, and certain BC 1.2 complaint USB HUBs cannot be detected. Increase delay to 40ms allowing enough time for primary detection.
During secondary detection the i.MX is required to disable VDP_SRC and IDM_SNK, and enable VDM_SRC and IDP_SINK for at least 40ms (TVDMSRC_ON).
Current implementation is not disabling VDP_SRC and IDM_SNK, introduce disable sequence in imx7d_charger_secondary_detection() function.
VDM_SRC and IDP_SINK should be enabled for at least 40ms (TVDMSRC_ON). Increase delay allowing enough time for detection.
--- drivers/usb/chipidea/usbmisc_imx.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
drivers/usb/chipidea/usbmisc_imx.c +14 -2
@@ -686,6 +686,16 @@ static int imx7d_charger_secondary_detecint val;unsigned long flags; +/* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */ +spin_lock_irqsave (&usbmisc->lock, flags); + val =readl (usbmisc->base +MX7D_USB_OTG_PHY_CFG2 ); + val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 ; +writel (val, usbmisc->base +MX7D_USB_OTG_PHY_CFG2 ); +spin_unlock_irqrestore (&usbmisc->lock, flags); + +/* TVDMSRC_DIS */ +msleep (20 ); +/* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */ spin_lock_irqsave (&usbmisc->lock, flags); val =readl (usbmisc->base +MX7D_USB_OTG_PHY_CFG2 );
@@ -695,7 +705,8 @@ static int imx7d_charger_secondary_detec usbmisc->base + MX7D_USB_OTG_PHY_CFG2);spin_unlock_irqrestore (&usbmisc->lock, flags); -usleep_range (1000 ,2000 ); +/* TVDMSRC_ON */ +msleep (40 );/* * Per BC 1.2, check voltage of D+:
@@ -798,7 +809,8 @@ static int imx7d_charger_primary_detecti usbmisc->base + MX7D_USB_OTG_PHY_CFG2);spin_unlock_irqrestore (&usbmisc->lock, flags); -usleep_range (1000 ,2000 ); +/* TVDPSRC_ON */ +msleep (40 );/* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */ val =readl (usbmisc->base +MX7D_USB_OTG_PHY_STATUS );
Greg Kroah-Hartman
maintainerPATCH 123/178 tracing: Do not stop recording cmdlines when tracing is off
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 85550c83da421fb12dc1816c45012e1e638d2b38 upstream.
The saved_cmdlines is used to map pids to the task name, such that the output of the tracing does not just show pids, but also gives a human readable name for the task.
If the name is not mapped, the output looks like this:
<...>-1316 [005] ...2 132.044039: ...
Instead of this:
gnome-shell-1316 [005] ...2 132.044039: ...
The names are updated when tracing is running, but are skipped if tracing is stopped. Unfortunately, this stops the recording of the names if the top level tracer is stopped, and not if there's other tracers active.
The recording of a name only happens when a new event is written into a ring buffer, so there is no need to test if tracing is on or not. If tracing is off, then no event is written and no need to test if tracing is off or not.
Remove the check, as it hides the names of tasks for events in the instance buffers.
--- kernel/trace/trace.c | 2 -- 1 file changed, 2 deletions(-)
kernel/trace/trace.c +0 -2
@@ -2486,8 +2486,6 @@ static bool tracing_record_taskinfo_skip {if (unlikely (!(flags & (TRACE_RECORD_CMDLINE |TRACE_RECORD_TGID ))))return true; -if (atomic_read (&trace_record_taskinfo_disabled) || !tracing_is_on ()) -return true;if (!__this_cpu_read (trace_taskinfo_save))return true;return false;
Greg Kroah-Hartman
maintainerPATCH 124/178 tracing: Do not stop recording comms if the trace file is being read
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 4fdd595e4f9a1ff6d93ec702eaecae451cfc6591 upstream.
A while ago, when the "trace" file was opened, tracing was stopped, and code was added to stop recording the comms to saved_cmdlines, for mapping of the pids to the task name.
Code has been added that only records the comm if a trace event occurred, and there's no reason to not trace it if the trace file is opened.
--- kernel/trace/trace.c | 9 --------- 1 file changed, 9 deletions(-)
kernel/trace/trace.c +0 -9
@@ -2198,9 +2198,6 @@ struct saved_cmdlines_buffer { };static struct saved_cmdlines_buffer *savedcmd; -/* temporary disable recording */ -static atomic_t trace_record_taskinfo_disabled__read_mostly ; -static inline char *get_saved_cmdlines (int idx) {return &savedcmd->saved_cmdlines[idx *TASK_COMM_LEN ];
@@ -3740,9 +3737,6 @@ static void *s_start(struct seq_file *m,return ERR_PTR (-EBUSY );#endif -if (!iter->snapshot) -atomic_inc (&trace_record_taskinfo_disabled); -if (*pos != iter->pos) { iter->ent =NULL ; iter->cpu =0 ;
@@ -3785,9 +3779,6 @@ static void s_stop(struct seq_file *m, vreturn ;#endif -if (!iter->snapshot) -atomic_dec (&trace_record_taskinfo_disabled); -trace_access_unlock (iter->cpu_file);trace_event_read_unlock (); }
Greg Kroah-Hartman
maintainerPATCH 125/178 tracing: Do no increment trace_clock_global() by one
In reply to Greg Kroah-HartmanFrom: Steven Rostedt (VMware) <[email protected]>
commit 89529d8b8f8daf92d9979382b8d2eb39966846ea upstream.
The trace_clock_global() tries to make sure the events between CPUs is somewhat in order. A global value is used and updated by the latest read of a clock. If one CPU is ahead by a little, and is read by another CPU, a lock is taken, and if the timestamp of the other CPU is behind, it will simply use the other CPUs timestamp.
The lock is also only taken with a "trylock" due to tracing, and strange recursions can happen. The lock is not taken at all in NMI context.
In the case where the lock is not able to be taken, the non synced timestamp is returned. But it will not be less than the saved global timestamp.
The problem arises because when the time goes "backwards" the time returned is the saved timestamp plus 1. If the lock is not taken, and the plus one to the timestamp is returned, there's a small race that can cause the time to go backwards!
CPU0 CPU1
---- ----
trace_clock_global() {
ts = clock() [ 1000 ]
trylock(clock_lock) [ success ]
global_ts = ts; [ 1000 ]
<interrupted by NMI>
trace_clock_global() {
ts = clock() [ 999 ]
if (ts < global_ts)
ts = global_ts + 1 [ 1001 ]
trylock(clock_lock) [ fail ]
return ts [ 1001]
}
unlock(clock_lock);
return ts; [ 1000 ]
} trace_clock_global() {
ts = clock() [ 1000 ]
if (ts < global_ts) [ false 1000 == 1000 ]
trylock(clock_lock) [ success ]
global_ts = ts; [ 1000 ]
unlock(clock_lock)
return ts; [ 1000 ]}
The above case shows to reads of trace_clock_global() on the same CPU, but the second read returns one less than the first read. That is, time when backwards, and this is not what is allowed by trace_clock_global().
This was triggered by heavy tracing and the ring buffer checker that tests for the clock going backwards:
Ring buffer clock went backwards: 20613921464 -> 20613921463
------------[ cut here ]------------ WARNING: CPU: 2 PID: 0 at kernel/trace/ring_buffer.c:3412 check_buffer+0x1b9/0x1c0 Modules linked in: [..] [CPU: 2]TIME DOES NOT MATCH expected:20620711698 actual:20620711697 delta:6790234 before:20613921463 after:20613921463 [20613915818] PAGE TIME STAMP [20613915818] delta:0 [20613915819] delta:1 [20613916035] delta:216 [20613916465] delta:430 [20613916575] delta:110 [20613916749] delta:174 [20613917248] delta:499 [20613917333] delta:85 [20613917775] delta:442 [20613917921] delta:146 [20613918321] delta:400 [20613918568] delta:247 [20613918768] delta:200 [20613919306] delta:538 [20613919353] delta:47 [20613919980] delta:627 [20613920296] delta:316 [20613920571] delta:275 [20613920862] delta:291 [20613921152] delta:290 [20613921464] delta:312 [20613921464] delta:0 TIME EXTEND [20613921464] delta:0
This happened more than once, and always for an off by one result. It also started happening after commit aafe104aa9096 was added.
--- kernel/trace/trace_clock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/trace_clock.c +3 -3
@@ -115,9 +115,9 @@ u64 notrace trace_clock_global(void) prev_time =READ_ONCE (trace_clock_struct.prev_time); now =sched_clock_cpu (this_cpu); -/* Make sure that now is always greater than prev_time */ +/* Make sure that now is always greater than or equal to prev_time */ if ((s64)(now - prev_time) <0 ) - now = prev_time +1 ; + now = prev_time;/* * If in an NMI context then dont risk lockups and simply return
@@ -131,7 +131,7 @@ u64 notrace trace_clock_global(void)/* Reread prev_time in case it was already updated */ prev_time =READ_ONCE (trace_clock_struct.prev_time);if ((s64)(now - prev_time) <0 ) - now = prev_time +1 ; + now = prev_time; trace_clock_struct.prev_time = now;
Greg Kroah-Hartman
maintainerPATCH 126/178 PCI: Mark TI C667X to avoid bus reset
In reply to Greg Kroah-HartmanFrom: Antti Järvinen <[email protected]>
commit b5cf198e74a91073d12839a3e2db99994a39995d upstream.
Some TI KeyStone C667X devices do not support bus/hot reset. The PCIESS automatically disables LTSSM when Secondary Bus Reset is received and device stops working. Prevent bus reset for these devices. With this change, the device can be assigned to VMs with VFIO, but it will leak state between VMs.
Reference: https://e2e.ti.com/support/processors/f/791/t/954382
--- drivers/pci/quirks.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/pci/quirks.c +10 -0
@@ -3578,6 +3578,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_A*/ DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_CAVIUM ,0xa100 , quirk_no_bus_reset); +/* +* Some TI KeyStone C667X devices do not support bus/hot reset. The PCIESS +* automatically disables LTSSM when Secondary Bus Reset is received and +* the device stops working. Prevent bus reset for these devices. With +* this change, the device can be assigned to VMs with VFIO, but it will +* leak state between VMs. Reference +* https://e2e.ti.com/support/processors/f/791/t/954382 +*/ +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_TI ,0xb005 , quirk_no_bus_reset); +static void quirk_no_pm_reset (struct pci_dev *dev) {/*
Greg Kroah-Hartman
maintainerPATCH 127/178 PCI: Mark some NVIDIA GPUs to avoid bus reset
In reply to Greg Kroah-HartmanFrom: Shanker Donthineni <[email protected]>
commit 4c207e7121fa92b66bf1896bf8ccb9edfb0f9731 upstream.
Some NVIDIA GPU devices do not work with SBR. Triggering SBR leaves the device inoperable for the current system boot. It requires a system hard-reboot to get the GPU device back to normal operating condition post-SBR. For the affected devices, enable NO_BUS_RESET quirk to avoid the issue.
This issue will be fixed in the next generation of hardware.
--- drivers/pci/quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/pci/quirks.c +12 -0
@@ -3559,6 +3559,18 @@ static void quirk_no_bus_reset(struct pc }/* +* Some NVIDIA GPU devices do not work with bus reset, SBR needs to be +* prevented for those affected devices. +*/ +static void quirk_nvidia_no_bus_reset (struct pci_dev *dev) +{ +if ((dev->device &0xffc0 ) ==0x2340 ) +quirk_no_bus_reset (dev); +} +DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_NVIDIA ,PCI_ANY_ID , + quirk_nvidia_no_bus_reset); + +/* * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. * The device will throw a Link Down error on AER-capable systems and * regardless of AER, config space of the device is never accessible again
Greg Kroah-Hartman
maintainerPATCH 128/178 PCI: Mark AMD Navi14 GPU ATS as broken
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
commit e8946a53e2a698c148b3b3ed732f43c7747fbeb6 upstream.
Observed unexpected GPU hang during runpm stress test on 0x7341 rev 0x00. Further debugging shows broken ATS is related.
Disable ATS on this part. Similar issues on other devices:
a2da5d8cc0b0 ("PCI: Mark AMD Raven iGPU ATS as broken in some platforms") 45beb31d3afb ("PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken") 5e89cd303e3a ("PCI: Mark AMD Navi14 GPU rev 0xc5 ATS as broken")
--- drivers/pci/quirks.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/pci/quirks.c +3 -1
@@ -5187,7 +5187,8 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SEstatic void quirk_amd_harvest_no_ats (struct pci_dev *pdev) {if ((pdev->device ==0x7312 && pdev->revision !=0x00 ) || - (pdev->device ==0x7340 && pdev->revision !=0xc5 )) + (pdev->device ==0x7340 && pdev->revision !=0xc5 ) || + (pdev->device ==0x7341 && pdev->revision !=0x00 ))return ;if (pdev->device ==0x15d8 ) {
@@ -5214,6 +5215,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATDECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_ATI ,0x7312 , quirk_amd_harvest_no_ats);/* AMD Navi14 dGPU */ DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_ATI ,0x7340 , quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_ATI ,0x7341 , quirk_amd_harvest_no_ats);/* AMD Raven platform iGPU */ DECLARE_PCI_FIXUP_FINAL (PCI_VENDOR_ID_ATI ,0x15d8 , quirk_amd_harvest_no_ats);#endif /* CONFIG_PCI_ATS */
Greg Kroah-Hartman
maintainerPATCH 129/178 PCI: aardvark: Fix kernel panic during PIO transfer
In reply to Greg Kroah-HartmanFrom: Pali Rohár <[email protected]>
commit f18139966d072dab8e4398c95ce955a9742e04f7 upstream.
Trying to start a new PIO transfer by writing value 0 in PIO_START register when previous transfer has not yet completed (which is indicated by value 1 in PIO_START) causes an External Abort on CPU, which results in kernel panic:
SError Interrupt on CPU0, code 0xbf000002 -- SError Kernel panic - not syncing: Asynchronous SError Interrupt
To prevent kernel panic, it is required to reject a new PIO transfer when previous one has not finished yet.
If previous PIO transfer is not finished yet, the kernel may issue a new PIO request only if the previous PIO transfer timed out.
In the past the root cause of this issue was incorrectly identified (as it often happens during link retraining or after link down event) and special hack was implemented in Trusted Firmware to catch all SError events in EL3, to ignore errors with code 0xbf000002 and not forwarding any other errors to kernel and instead throw panic from EL3 Trusted Firmware handler.
Links to discussion and patches about this issue:
https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50
https://lore.kernel.org/linux-pci/[email protected]/
https://lore.kernel.org/linux-pci/[email protected]/
https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/1541
But the real cause was the fact that during link retraining or after link down event the PIO transfer may take longer time, up to the 1.44s until it times out. This increased probability that a new PIO transfer would be issued by kernel while previous one has not finished yet.
After applying this change into the kernel, it is possible to revert the mentioned TF-A hack and SError events do not have to be caught in TF-A EL3.
--- drivers/pci/controller/pci-aardvark.c | 49 +++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-)
drivers/pci/controller/pci-aardvark.c +40 -9
@@ -514,7 +514,7 @@ static int advk_pcie_wait_pio(struct advudelay (PIO_RETRY_DELAY ); } -dev_err (dev,"config read/write timed out\n" ); +dev_err (dev,"PIO read/write transfer time out\n" );return -ETIMEDOUT ; }
@@ -657,6 +657,35 @@ static bool advk_pcie_valid_device(strucreturn true; } +static bool advk_pcie_pio_is_running (struct advk_pcie *pcie) +{ +struct device *dev = &pcie->pdev->dev; + +/* +* Trying to start a new PIO transfer when previous has not completed +* cause External Abort on CPU which results in kernel panic: +* +* SError Interrupt on CPU0, code 0xbf000002 -- SError +* Kernel panic - not syncing: Asynchronous SError Interrupt +* +* Functions advk_pcie_rd_conf() and advk_pcie_wr_conf() are protected +* by raw_spin_lock_irqsave() at pci_lock_config() level to prevent +* concurrent calls at the same time. But because PIO transfer may take +* about 1.5s when link is down or card is disconnected, it means that +* advk_pcie_wait_pio() does not always have to wait for completion. +* +* Some versions of ARM Trusted Firmware handles this External Abort at +* EL3 level and mask it to prevent kernel panic. Relevant TF-A commit: +* https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50 +*/ +if (advk_readl (pcie,PIO_START )) { +dev_err (dev,"Previous PIO read/write transfer is still running\n" ); +return true; + } + +return false; +} +static int advk_pcie_rd_conf (struct pci_bus *bus,u32 devfn,int where,int size,u32 *val) {
@@ -673,9 +702,10 @@ static int advk_pcie_rd_conf(struct pci_return pci_bridge_emul_conf_read (&pcie->bridge, where, size, val); -/* Start PIO */ -advk_writel (pcie,0 ,PIO_START ); -advk_writel (pcie,1 ,PIO_ISR ); +if (advk_pcie_pio_is_running (pcie)) { + *val =0xffffffff ; +return PCIBIOS_SET_FAILED ; + }/* Program the control register */ reg =advk_readl (pcie,PIO_CTRL );
@@ -694,7 +724,8 @@ static int advk_pcie_rd_conf(struct pci_/* Program the data strobe */ advk_writel (pcie,0xf ,PIO_WR_DATA_STRB ); -/* Start the transfer */ +/* Clear PIO DONE ISR and start the transfer */ +advk_writel (pcie,1 ,PIO_ISR );advk_writel (pcie,1 ,PIO_START ); ret =advk_pcie_wait_pio (pcie);
@@ -734,9 +765,8 @@ static int advk_pcie_wr_conf(struct pci_if (where % size)return PCIBIOS_SET_FAILED ; -/* Start PIO */ -advk_writel (pcie,0 ,PIO_START ); -advk_writel (pcie,1 ,PIO_ISR ); +if (advk_pcie_pio_is_running (pcie)) +return PCIBIOS_SET_FAILED ;/* Program the control register */ reg =advk_readl (pcie,PIO_CTRL );
@@ -763,7 +793,8 @@ static int advk_pcie_wr_conf(struct pci_/* Program the data strobe */ advk_writel (pcie, data_strobe,PIO_WR_DATA_STRB ); -/* Start the transfer */ +/* Clear PIO DONE ISR and start the transfer */ +advk_writel (pcie,1 ,PIO_ISR );advk_writel (pcie,1 ,PIO_START ); ret =advk_pcie_wait_pio (pcie);
Greg Kroah-Hartman
maintainerPATCH 130/178 PCI: Add ACS quirk for Broadcom BCM57414 NIC
In reply to Greg Kroah-HartmanFrom: Sriharsha Basavapatna <[email protected]>
commit db2f77e2bd99dbd2fb23ddde58f0fae392fe3338 upstream.
The Broadcom BCM57414 NIC may be a multi-function device. While it does not advertise an ACS capability, peer-to-peer transactions are not possible between the individual functions, so it is safe to treat them as fully isolated.
Add an ACS quirk for this device so the functions can be in independent IOMMU groups and attached individually to userspace applications using VFIO.
--- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/quirks.c +2 -0
@@ -4786,6 +4786,8 @@ static const struct pci_dev_acs_enabled { PCI_VENDOR_ID_AMPERE, 0xE00A, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs }, +/* Broadcom multi-function device */ + { PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs },/* Amazon Annapurna Labs */ { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs },
Greg Kroah-Hartman
maintainerPATCH 131/178 PCI: Work around Huawei Intelligent NIC VF FLR erratum
In reply to Greg Kroah-HartmanFrom: Chiqijun <[email protected]>
commit ce00322c2365e1f7b0312f2f493539c833465d97 upstream.
pcie_flr() starts a Function Level Reset (FLR), waits 100ms (the maximum time allowed for FLR completion by PCIe r5.0, sec 6.6.2), and waits for the FLR to complete. It assumes the FLR is complete when a config read returns valid data.
When we do an FLR on several Huawei Intelligent NIC VFs at the same time, firmware on the NIC processes them serially. The VF may respond to config reads before the firmware has completed its reset processing. If we bind a driver to the VF (e.g., by assigning the VF to a virtual machine) in the interval between the successful config read and completion of the firmware reset processing, the NIC VF driver may fail to load.
Prevent this driver failure by waiting for the NIC firmware to complete its reset processing. Not all NIC firmware supports this feature.
--- drivers/pci/quirks.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+)
drivers/pci/quirks.c +65 -0
@@ -3935,6 +3935,69 @@ static int delay_250ms_after_flr(structreturn 0 ; } +#define PCI_DEVICE_ID_HINIC_VF 0x375E +#define HINIC_VF_FLR_TYPE 0x1000 +#define HINIC_VF_FLR_CAP_BIT (1UL << 30) +#define HINIC_VF_OP 0xE80 +#define HINIC_VF_FLR_PROC_BIT (1UL << 18) +#define HINIC_OPERATION_TIMEOUT 15000/* 15 seconds */ + +/* Device-specific reset method for Huawei Intelligent NIC virtual functions */ +static int reset_hinic_vf_dev (struct pci_dev *pdev,int probe) +{ +unsigned long timeout; +void __iomem *bar; +u32 val; + +if (probe) +return 0 ; + + bar =pci_iomap (pdev,0 ,0 ); +if (!bar) +return -ENOTTY ; + +/* Get and check firmware capabilities */ + val =ioread32be (bar +HINIC_VF_FLR_TYPE ); +if (!(val &HINIC_VF_FLR_CAP_BIT )) { +pci_iounmap (pdev, bar); +return -ENOTTY ; + } + +/* Set HINIC_VF_FLR_PROC_BIT for the start of FLR */ + val =ioread32be (bar +HINIC_VF_OP ); + val = val |HINIC_VF_FLR_PROC_BIT ; +iowrite32be (val, bar +HINIC_VF_OP ); + +pcie_flr (pdev); + +/* +* The device must recapture its Bus and Device Numbers after FLR +* in order generate Completions. Issue a config write to let the +* device capture this information. +*/ +pci_write_config_word (pdev,PCI_VENDOR_ID ,0 ); + +/* Firmware clears HINIC_VF_FLR_PROC_BIT when reset is complete */ + timeout = jiffies +msecs_to_jiffies (HINIC_OPERATION_TIMEOUT ); +do { + val =ioread32be (bar +HINIC_VF_OP ); +if (!(val &HINIC_VF_FLR_PROC_BIT )) + goto reset_complete; +msleep (20 ); + }while (time_before (jiffies, timeout)); + + val =ioread32be (bar +HINIC_VF_OP ); +if (!(val &HINIC_VF_FLR_PROC_BIT )) + goto reset_complete; + +pci_warn (pdev,"Reset dev timeout, FLR ack reg: %#010x\n" , val); + +reset_complete: +pci_iounmap (pdev, bar); + +return 0 ; +} +static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { {PCI_VENDOR_ID_INTEL ,PCI_DEVICE_ID_INTEL_82599_SFP_VF , reset_intel_82599_sfp_virtfn },
@@ -3946,6 +4009,8 @@ static const struct pci_dev_reset_method { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr }, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, reset_chelsio_generic_dev }, + { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, + reset_hinic_vf_dev }, { 0 } };
Greg Kroah-Hartman
maintainerPATCH 132/178 btrfs: zoned: fix negative space_info->bytes_readonly
In reply to Greg Kroah-HartmanFrom: Naohiro Aota <[email protected]>
commit f9f28e5bd0baee9708c9011897196f06ae3a2733 upstream.
Consider we have a using block group on zoned btrfs.
|<- ZU ->|<- used ->|<---free--->|
`- Alloc offset
ZU: Zone unusable
Marking the block group read-only will migrate the zone unusable bytes to the read-only bytes. So, we will have this.
|<- RO ->|<- used ->|<--- RO --->|
RO: Read only
When marking it back to read-write, btrfs_dec_block_group_ro() subtracts the above "RO" bytes from the space_info->bytes_readonly. And, it moves the zone unusable bytes back and again subtracts those bytes from the space_info->bytes_readonly, leading to negative bytes_readonly.
This can be observed in the output as eg.:
Data, single: total=512.00MiB, used=165.21MiB, zone_unusable=16.00EiB Data, single: total=536870912, used=173256704, zone_unusable=18446744073603186688
This commit fixes the issue by reordering the operations.
--- fs/btrfs/block-group.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/btrfs/block-group.c +4 -4
@@ -2347,16 +2347,16 @@ void btrfs_dec_block_group_ro(struct btrspin_lock (&sinfo->lock);spin_lock (&cache->lock);if (!--cache->ro) { - num_bytes = cache->length - cache->reserved - - cache->pinned - cache->bytes_super - - cache->zone_unusable - cache->used; - sinfo->bytes_readonly -= num_bytes;if (btrfs_is_zoned (cache->fs_info)) {/* Migrate zone_unusable bytes back */ cache->zone_unusable = cache->alloc_offset - cache->used; sinfo->bytes_zone_unusable += cache->zone_unusable; sinfo->bytes_readonly -= cache->zone_unusable; } + num_bytes = cache->length - cache->reserved - + cache->pinned - cache->bytes_super - + cache->zone_unusable - cache->used; + sinfo->bytes_readonly -= num_bytes;list_del_init (&cache->ro_list); }spin_unlock (&cache->lock);
Greg Kroah-Hartman
maintainerPATCH 133/178 s390/mcck: fix invalid KVM guest condition check
In reply to Greg Kroah-HartmanFrom: Alexander Gordeev <[email protected]>
commit 1874cb13d5d7cafa61ce93a760093ebc5485b6ab upstream.
Wrong condition check is used to decide if a machine check hit while in KVM guest. As result of this check the instruction following the SIE critical section might be considered as still in KVM guest and _CIF_MCCK_GUEST CPU flag mistakenly set as result.
--- arch/s390/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/entry.S +1 -1
@@ -653,7 +653,7 @@ ENDPROC(stack_overflow) slgr %r9,%r13 larl %r13,.Lsie_skip clgr %r9,%r13 - jh .Lcleanup_sie_int + jhe .Lcleanup_sie_int oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST .Lcleanup_sie_int: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST)
Greg Kroah-Hartman
maintainerPATCH 134/178 KVM: x86: Immediately reset the MMU context when the SMM flag is cleared
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 78fcb2c91adfec8ce3a2ba6b4d0dda89f2f4a7c6 upstream.
Immediately reset the MMU context when the vCPU's SMM flag is cleared so that the SMM flag in the MMU role is always synchronized with the vCPU's flag. If RSM fails (which isn't correctly emulated), KVM will bail without calling post_leave_smm() and leave the MMU in a bad state.
The bad MMU role can lead to a NULL pointer dereference when grabbing a shadow page's rmap for a page fault as the initial lookups for the gfn will happen with the vCPU's SMM flag (=0), whereas the rmap lookup will use the shadow page's SMM flag, which comes from the MMU (=1). SMM has an entirely different set of memslots, and so the initial lookup can find a memslot (SMM=0) and then explode on the rmap memslot lookup (SMM=1).
general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 PID: 8410 Comm: syz-executor382 Not tainted 5.13.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:__gfn_to_rmap arch/x86/kvm/mmu/mmu.c:935 [inline] RIP: 0010:gfn_to_rmap+0x2b0/0x4d0 arch/x86/kvm/mmu/mmu.c:947 Code: <42> 80 3c 20 00 74 08 4c 89 ff e8 f1 79 a9 00 4c 89 fb 4d 8b 37 44 RSP: 0018:ffffc90000ffef98 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888015b9f414 RCX: ffff888019669c40 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000001 RBP: 0000000000000001 R08: ffffffff811d9cdb R09: ffffed10065a6002 R10: ffffed10065a6002 R11: 0000000000000000 R12: dffffc0000000000 R13: 0000000000000003 R14: 0000000000000001 R15: 0000000000000000 FS: 000000000124b300(0000) GS:ffff8880b9b00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000028e31000 CR4: 00000000001526e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: rmap_add arch/x86/kvm/mmu/mmu.c:965 [inline] mmu_set_spte+0x862/0xe60 arch/x86/kvm/mmu/mmu.c:2604 __direct_map arch/x86/kvm/mmu/mmu.c:2862 [inline] direct_page_fault+0x1f74/0x2b70 arch/x86/kvm/mmu/mmu.c:3769 kvm_mmu_do_page_fault arch/x86/kvm/mmu.h:124 [inline] kvm_mmu_page_fault+0x199/0x1440 arch/x86/kvm/mmu/mmu.c:5065 vmx_handle_exit+0x26/0x160 arch/x86/kvm/vmx/vmx.c:6122 vcpu_enter_guest+0x3bdd/0x9630 arch/x86/kvm/x86.c:9428 vcpu_run+0x416/0xc20 arch/x86/kvm/x86.c:9494 kvm_arch_vcpu_ioctl_run+0x4e8/0xa40 arch/x86/kvm/x86.c:9722 kvm_vcpu_ioctl+0x70f/0xbb0 arch/x86/kvm/../../../virt/kvm/kvm_main.c:3460 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:1069 [inline] __se_sys_ioctl+0xfb/0x170 fs/ioctl.c:1055 do_syscall_64+0x3f/0xb0 arch/x86/entry/common.c:47 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x440ce9
Message-Id: <[email protected]>
--- arch/x86/kvm/x86.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/x86/kvm/x86.c +4 -1
@@ -6991,7 +6991,10 @@ static unsigned emulator_get_hflags(strustatic void emulator_set_hflags (struct x86_emulate_ctxt *ctxt,unsigned emul_flags) { -emul_to_vcpu (ctxt)->arch.hflags = emul_flags; +struct kvm_vcpu *vcpu =emul_to_vcpu (ctxt); + + vcpu->arch.hflags = emul_flags; +kvm_mmu_reset_context (vcpu); } static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt,
Greg Kroah-Hartman
maintainerPATCH 135/178 KVM: x86/mmu: Calculate and check "full" mmu_role for nested MMU
In reply to Greg Kroah-HartmanFrom: Sean Christopherson <[email protected]>
commit 654430efde27248be563df9a88631204b5fe2df2 upstream.
Calculate and check the full mmu_role when initializing the MMU context for the nested MMU, where "full" means the bits and pieces of the role that aren't handled by kvm_calc_mmu_role_common(). While the nested MMU isn't used for shadow paging, things like the number of levels in the guest's page tables are surprisingly important when walking the guest page tables. Failure to reinitialize the nested MMU context if L2's paging mode changes can result in unexpected and/or missed page faults, and likely other explosions.
E.g. if an L1 vCPU is running both a 32-bit PAE L2 and a 64-bit L2, the "common" role calculation will yield the same role for both L2s. If the 64-bit L2 is run after the 32-bit PAE L2, L0 will fail to reinitialize the nested MMU context, ultimately resulting in a bad walk of L2's page tables as the MMU will still have a guest root_level of PT32E_ROOT_LEVEL.
WARNING: CPU: 4 PID: 167334 at arch/x86/kvm/vmx/vmx.c:3075 ept_save_pdptrs+0x15/0xe0 [kvm_intel] Modules linked in: kvm_intel] CPU: 4 PID: 167334 Comm: CPU 3/KVM Not tainted 5.13.0-rc1-d849817d5673-reqs #185 Hardware name: ASUS Q87M-E/Q87M-E, BIOS 1102 03/03/2014 RIP: 0010:ept_save_pdptrs+0x15/0xe0 [kvm_intel] Code: <0f> 0b c3 f6 87 d8 02 00f RSP: 0018:ffffbba702dbba00 EFLAGS: 00010202 RAX: 0000000000000011 RBX: 0000000000000002 RCX: ffffffff810a2c08 RDX: ffff91d7bc30acc0 RSI: 0000000000000011 RDI: ffff91d7bc30a600 RBP: ffff91d7bc30a600 R08: 0000000000000010 R09: 0000000000000007 R10: 0000000000000000 R11: 0000000000000000 R12: ffff91d7bc30a600 R13: ffff91d7bc30acc0 R14: ffff91d67c123460 R15: 0000000115d7e005 FS: 00007fe8e9ffb700(0000) GS:ffff91d90fb00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 000000029f15a001 CR4: 00000000001726e0 Call Trace: kvm_pdptr_read+0x3a/0x40 [kvm] paging64_walk_addr_generic+0x327/0x6a0 [kvm] paging64_gva_to_gpa_nested+0x3f/0xb0 [kvm] kvm_fetch_guest_virt+0x4c/0xb0 [kvm] __do_insn_fetch_bytes+0x11a/0x1f0 [kvm] x86_decode_insn+0x787/0x1490 [kvm] x86_decode_emulated_instruction+0x58/0x1e0 [kvm] x86_emulate_instruction+0x122/0x4f0 [kvm] vmx_handle_exit+0x120/0x660 [kvm_intel] kvm_arch_vcpu_ioctl_run+0xe25/0x1cb0 [kvm] kvm_vcpu_ioctl+0x211/0x5a0 [kvm] __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x40/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
Message-Id: <[email protected]>
--- arch/x86/kvm/mmu/mmu.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
arch/x86/kvm/mmu/mmu.c +25 -1
@@ -4726,9 +4726,33 @@ static void init_kvm_softmmu(struct kvm_ context->inject_page_fault = kvm_inject_page_fault; } +static union kvm_mmu_role kvm_calc_nested_mmu_role (struct kvm_vcpu *vcpu) +{ +union kvm_mmu_role role =kvm_calc_shadow_root_page_role_common (vcpu, false); + +/* +* Nested MMUs are used only for walking L2's gva->gpa, they never have +* shadow pages of their own and so "direct" has no meaning. Set it +* to "true" to try to detect bogus usage of the nested MMU. +*/ + role.base.direct = true; + +if (!is_paging (vcpu)) + role.base.level =0 ; +else if (is_long_mode (vcpu)) + role.base.level =is_la57_mode (vcpu) ?PT64_ROOT_5LEVEL : +PT64_ROOT_4LEVEL ; +else if (is_pae (vcpu)) + role.base.level =PT32E_ROOT_LEVEL ; +else + role.base.level =PT32_ROOT_LEVEL ; + +return role; +} +static void init_kvm_nested_mmu (struct kvm_vcpu *vcpu) { -union kvm_mmu_role new_role =kvm_calc_mmu_role_common (vcpu, false); +union kvm_mmu_role new_role =kvm_calc_nested_mmu_role (vcpu);struct kvm_mmu *g_context = &vcpu->arch.nested_mmu;if (new_role.as_u64 == g_context->mmu_role.as_u64)
Greg Kroah-Hartman
maintainerPATCH 136/178 KVM: X86: Fix x86_emulator slab cache leak
In reply to Greg Kroah-HartmanFrom: Wanpeng Li <[email protected]>
commit dfdc0a714d241bfbf951886c373cd1ae463fcc25 upstream.
Commit c9b8b07cded58 (KVM: x86: Dynamically allocate per-vCPU emulation context) tries to allocate per-vCPU emulation context dynamically, however, the x86_emulator slab cache is still exiting after the kvm module is unload as below after destroying the VM and unloading the kvm module.
grep x86_emulator /proc/slabinfox86_emulator 36 36 2672 12 8 : tunables 0 0 0 : slabdata 3 3 0
This patch fixes this slab cache leak by destroying the x86_emulator slab cache when the kvm module is unloaded.
Message-Id: <[email protected]>
--- arch/x86/kvm/x86.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kvm/x86.c +1 -0
@@ -8150,6 +8150,7 @@ void kvm_arch_exit(void) kvm_x86_ops.hardware_enable =NULL ;kvm_mmu_module_exit ();free_percpu (user_return_msrs); +kmem_cache_destroy (x86_emulator_cache);kmem_cache_destroy (x86_fpu_cache);#ifdef CONFIG_KVM_XEN static_key_deferred_flush (&kvm_xen_enabled);
Greg Kroah-Hartman
maintainerPATCH 137/178 s390/mcck: fix calculation of SIE critical section size
In reply to Greg Kroah-HartmanFrom: Alexander Gordeev <[email protected]>
commit 5bcbe3285fb614c49db6b238253f7daff7e66312 upstream.
The size of SIE critical section is calculated wrongly as result of a missed subtraction in commit 0b0ed657fe00 ("s390: remove critical section cleanup from entry.S")
--- arch/s390/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/s390/kernel/entry.S +1 -1
@@ -651,7 +651,7 @@ ENDPROC(stack_overflow) .Lcleanup_sie_mcck: larl %r13,.Lsie_entry slgr %r9,%r13 - larl %r13,.Lsie_skip + lghi %r13,.Lsie_skip - .Lsie_entry clgr %r9,%r13 jhe .Lcleanup_sie_int oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST
Greg Kroah-Hartman
maintainerPATCH 138/178 s390/ap: Fix hanging ioctl caused by wrong msg counter
In reply to Greg Kroah-HartmanFrom: Harald Freudenberger <[email protected]>
commit e73a99f3287a740a07d6618e9470f4d6cb217da8 upstream.
When a AP queue is switched to soft offline, all pending requests are purged out of the pending requests list and 'received' by the upper layer like zcrypt device drivers. This is also done for requests which are already enqueued into the firmware queue. A request in a firmware queue may eventually produce an response message, but there is no waiting process any more. However, the response was counted with the queue_counter and as this counter was reset to 0 with the offline switch, the pending response caused the queue_counter to get negative. The next request increased this counter to 0 (instead of 1) which caused the ap code to assume there is nothing to receive and so the response for this valid request was never tried to fetch from the firmware queue.
This all caused a queue to not work properly after a switch offline/online and in the end processes to hang forever when trying to send a crypto request after an queue offline/online switch cicle.
Fixed by a) making sure the counter does not drop below 0 and b) on a successful enqueue of a message has at least a value of 1.
Additionally a warning is emitted, when a reply can't get assigned to a waiting process. This may be normal operation (process had timeout or has been killed) but may give a hint that something unexpected happened (like this odd behavior described above).
--- drivers/s390/crypto/ap_queue.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/s390/crypto/ap_queue.c +9 -2
@@ -135,12 +135,13 @@ static struct ap_queue_status ap_sm_recv {struct ap_queue_status status;struct ap_message *ap_msg; +bool found = false; status =ap_dqap (aq->qid, &aq->reply->psmid, aq->reply->msg, aq->reply->len);switch (status.response_code) {case AP_RESPONSE_NORMAL : - aq->queue_count--; + aq->queue_count =max_t (int,0 , aq->queue_count -1 );if (aq->queue_count >0 )mod_timer (&aq->timeout, jiffies + aq->request_timeout);
@@ -150,8 +151,14 @@ static struct ap_queue_status ap_sm_recvlist_del_init (&ap_msg->list); aq->pendingq_count--; ap_msg->receive (aq, ap_msg, aq->reply); + found = true;break ; } +if (!found) { +AP_DBF_WARN ("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n" , + __func__, aq->reply->psmid, +AP_QID_CARD (aq->qid),AP_QID_QUEUE (aq->qid)); + } fallthrough;case AP_RESPONSE_NO_PENDING_REPLY :if (!status.queue_empty || aq->queue_count <=0 )
@@ -232,7 +239,7 @@ static enum ap_sm_wait ap_sm_write(struc ap_msg->flags & AP_MSG_FLAG_SPECIAL);switch (status.response_code) {case AP_RESPONSE_NORMAL : - aq->queue_count++; + aq->queue_count =max_t (int,1 , aq->queue_count +1 );if (aq->queue_count ==1 )mod_timer (&aq->timeout, jiffies + aq->request_timeout);list_move_tail (&ap_msg->list, &aq->pendingq);
Greg Kroah-Hartman
maintainerPATCH 139/178 ARCv2: save ABI registers across signal handling
In reply to Greg Kroah-HartmanFrom: Vineet Gupta <[email protected]>
commit 96f1b00138cb8f04c742c82d0a7c460b2202e887 upstream.
ARCv2 has some configuration dependent registers (r30, r58, r59) which could be targetted by the compiler. To keep the ABI stable, these were unconditionally part of the glibc ABI (sysdeps/unix/sysv/linux/arc/sys/ucontext.h:mcontext_t) however we missed populating them (by saving/restoring them across signal handling).
This patch fixes the issue by
- adding arcv2 ABI regs to kernel struct sigcontext
- populating them during signal handling
Change to struct sigcontext might seem like a glibc ABI change (although it primarily uses ucontext_t:mcontext_t) but the fact is
- it has only been extended (existing fields are not touched)
- the old sigcontext was ABI incomplete to begin with anyways
--- arch/arc/include/uapi/asm/sigcontext.h | 1 arch/arc/kernel/signal.c | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+)
arch/arc/include/uapi/asm/sigcontext.h +1 -0
@@ -18,6 +18,7 @@*/ struct sigcontext {struct user_regs_struct regs; +struct user_regs_arcv2 v2abi; };#endif /* _ASM_ARC_SIGCONTEXT_H */
arch/arc/kernel/signal.c +43 -0
61 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 140/178 x86/mm: Avoid truncating memblocks for SGX memory
In reply to Greg Kroah-HartmanFrom: Fan Du <[email protected]>
commit 28e5e44aa3f4e0e0370864ed008fb5e2d85f4dc8 upstream.
tl;dr:
Several SGX users reported seeing the following message on NUMA systems:
sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0.
This turned out to be the memblock code mistakenly throwing away SGX memory.
=== Full Changelog ===
The 'max_pfn' variable represents the highest known RAM address. It can be used, for instance, to quickly determine for which physical addresses there is mem_map[] space allocated. The numa_meminfo code makes an effort to throw out ("trim") all memory blocks which are above 'max_pfn'.
SGX memory is not considered RAM (it is marked as "Reserved" in the e820) and is not taken into account by max_pfn. Despite this, SGX memory areas have NUMA affinity and are enumerated in the ACPI SRAT table. The existing SGX code uses the numa_meminfo mechanism to look up the NUMA affinity for its memory areas.
In cases where SGX memory was above max_pfn (usually just the one EPC section in the last highest NUMA node), the numa_memblock is truncated at 'max_pfn', which is below the SGX memory. When the SGX code tries to look up the affinity of this memory, it fails and produces an error message:
sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0.
and assigns the memory to NUMA node 0.
Instead of silently truncating the memory block at 'max_pfn' and dropping the SGX memory, add the truncated portion to 'numa_reserved_meminfo'. This allows the SGX code to later determine the NUMA affinity of its 'Reserved' area.
Before, numa_meminfo looked like this (from 'crash'):
blk = { start = 0x0, end = 0x2080000000, nid = 0x0 }
{ start = 0x2080000000, end = 0x4000000000, nid = 0x1 }numa_reserved_meminfo is empty.
With this, numa_meminfo looks like this:
blk = { start = 0x0, end = 0x2080000000, nid = 0x0 }
{ start = 0x2080000000, end = 0x4000000000, nid = 0x1 }and numa_reserved_meminfo has an entry for node 1's SGX memory:
blk = { start = 0x4000000000, end = 0x4080000000, nid = 0x1 }
[ daveh: completely rewrote/reworked changelog ]
--- arch/x86/mm/numa.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/mm/numa.c +7 -1
@@ -254,7 +254,13 @@ int __init numa_cleanup_meminfo(struct n/* make sure all non-reserved blocks are inside the limits */ bi->start =max (bi->start, low); - bi->end =min (bi->end, high); + +/* preserve info for non-RAM areas above 'max_pfn': */ +if (bi->end > high) { +numa_add_memblk_to (bi->nid, high, bi->end, + &numa_reserved_meminfo); + bi->end = high; + }/* and there's no empty block */ if (bi->start >= bi->end)
Greg Kroah-Hartman
maintainerPATCH 141/178 x86/process: Check PF_KTHREAD and not current->mm for kernel threads
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 12f7764ac61200e32c916f038bdc08f884b0b604 upstream.
switch_fpu_finish() checks current->mm as indicator for kernel threads. That's wrong because kernel threads can temporarily use a mm of a user process via kthread_use_mm().
Check the task flags for PF_KTHREAD instead.
--- arch/x86/include/asm/fpu/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/fpu/internal.h +1 -1
@@ -578,7 +578,7 @@ static inline void switch_fpu_finish(str* PKRU state is switched eagerly because it needs to be valid before we * return to userland e.g. for a copy_to_user() operation. */ -if (current->mm) { +if (!(current->flags &PF_KTHREAD )) { pk =get_xsave_addr (&new_fpu->state.xsave,XFEATURE_PKRU );if (pk) pkru_val = pk->pkru;
Greg Kroah-Hartman
maintainerPATCH 142/178 x86/ioremap: Map EFI-reserved memory as encrypted for SEV
In reply to Greg Kroah-HartmanFrom: Tom Lendacky <[email protected]>
commit 8d651ee9c71bb12fc0c8eb2786b66cbe5aa3e43b upstream.
Some drivers require memory that is marked as EFI boot services data. In order for this memory to not be re-used by the kernel after ExitBootServices(), efi_mem_reserve() is used to preserve it by inserting a new EFI memory descriptor and marking it with the EFI_MEMORY_RUNTIME attribute.
Under SEV, memory marked with the EFI_MEMORY_RUNTIME attribute needs to be mapped encrypted by Linux, otherwise the kernel might crash at boot like below:
EFI Variables Facility v0.08 2004-May-17
general protection fault, probably for non-canonical address 0x3597688770a868b2: 0000 [#1] SMP NOPTI CPU: 13 PID: 1 Comm: swapper/0 Not tainted 5.12.4-2-default #1 openSUSE Tumbleweed Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:efi_mokvar_entry_next [...] Call Trace: efi_mokvar_sysfs_init ? efi_mokvar_table_init do_one_initcall ? __kmalloc kernel_init_freeable ? rest_init kernel_init ret_from_fork
Expand the __ioremap_check_other() function to additionally check for this other type of boot data reserved at runtime and indicate that it should be mapped encrypted for an SEV guest.
[ bp: Massage commit message. ]
--- arch/x86/mm/ioremap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/mm/ioremap.c +3 -1
@@ -118,7 +118,9 @@ static void __ioremap_check_other(resourif (!IS_ENABLED (CONFIG_EFI ))return ; -if (efi_mem_type (addr) ==EFI_RUNTIME_SERVICES_DATA ) +if (efi_mem_type (addr) ==EFI_RUNTIME_SERVICES_DATA || + (efi_mem_type (addr) ==EFI_BOOT_SERVICES_DATA && +efi_mem_attributes (addr) &EFI_MEMORY_RUNTIME )) desc->flags |=IORES_MAP_ENCRYPTED ; }
Greg Kroah-Hartman
maintainerPATCH 143/178 x86/pkru: Write hardware init value to PKRU when xstate is init
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 510b80a6a0f1a0d114c6e33bcea64747d127973c upstream.
When user space brings PKRU into init state, then the kernel handling is broken:
T1 user space
xsave(state)
state.header.xfeatures &= ~XFEATURE_MASK_PKRU;
xrstor(state)
T1 -> kernel
schedule()
XSAVE(S) -> T1->xsave.header.xfeatures[PKRU] == 0
T1->flags |= TIF_NEED_FPU_LOAD; wrpkru();
schedule()
...
pk = get_xsave_addr(&T1->fpu->state.xsave, XFEATURE_PKRU);
if (pk)
wrpkru(pk->pkru);
else
wrpkru(DEFAULT_PKRU);Because the xfeatures bit is 0 and therefore the value in the xsave storage is not valid, get_xsave_addr() returns NULL and switch_to() writes the default PKRU. -> FAIL #1!
So that wrecks any copy_to/from_user() on the way back to user space which hits memory which is protected by the default PKRU value.
Assumed that this does not fail (pure luck) then T1 goes back to user space and because TIF_NEED_FPU_LOAD is set it ends up in
switch_fpu_return()
__fpregs_load_activate()
if (!fpregs_state_valid()) {
load_XSTATE_from_task();
}But if nothing touched the FPU between T1 scheduling out and back in, then the fpregs_state is still valid which means switch_fpu_return() does nothing and just clears TIF_NEED_FPU_LOAD. Back to user space with DEFAULT_PKRU loaded. -> FAIL #2!
The fix is simple: if get_xsave_addr() returns NULL then set the PKRU value to 0 instead of the restrictive default PKRU value in init_pkru_value.
[ bp: Massage in minor nitpicks from folks. ]
--- arch/x86/include/asm/fpu/internal.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/include/asm/fpu/internal.h +9 -2
@@ -579,9 +579,16 @@ static inline void switch_fpu_finish(str* return to userland e.g. for a copy_to_user() operation. */ if (!(current->flags &PF_KTHREAD )) { +/* +* If the PKRU bit in xsave.header.xfeatures is not set, +* then the PKRU component was in init state, which means +* XRSTOR will set PKRU to 0. If the bit is not set then +* get_xsave_addr() will return NULL because the PKRU value +* in memory is not valid. This means pkru_val has to be +* set to 0 and not to init_pkru_value. +*/ pk =get_xsave_addr (&new_fpu->state.xsave,XFEATURE_PKRU ); -if (pk) - pkru_val = pk->pkru; + pkru_val = pk ? pk->pkru :0 ; }__write_pkru (pkru_val); }
Greg Kroah-Hartman
maintainerPATCH 144/178 x86/fpu: Prevent state corruption in __fpu__restore_sig()
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit 484cea4f362e1eeb5c869abbfb5f90eae6421b38 upstream.
The non-compacted slowpath uses __copy_from_user() and copies the entire user buffer into the kernel buffer, verbatim. This means that the kernel buffer may now contain entirely invalid state on which XRSTOR will #GP. validate_user_xstate_header() can detect some of that corruption, but that leaves the onus on callers to clear the buffer.
Prior to XSAVES support, it was possible just to reinitialize the buffer, completely, but with supervisor states that is not longer possible as the buffer clearing code split got it backwards. Fixing that is possible but not corrupting the state in the first place is more robust.
Avoid corruption of the kernel XSAVE buffer by using copy_user_to_xstate() which validates the XSAVE header contents before copying the actual states to the kernel. copy_user_to_xstate() was previously only called for compacted-format kernel buffers, but it works for both compacted and non-compacted forms.
Using it for the non-compacted form is slower because of multiple __copy_from_user() operations, but that cost is less important than robust code in an already slow path.
[ Changelog polished by Dave Hansen ]
--- arch/x86/kernel/fpu/signal.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
arch/x86/kernel/fpu/signal.c +1 -8
@@ -405,14 +405,7 @@ static int __fpu__restore_sig(void __useif (use_xsave () && !fx_only) {u64 init_bv =xfeatures_mask_user () & ~user_xfeatures; -if (using_compacted_format ()) { - ret =copy_user_to_xstate (&fpu->state.xsave, buf_fx); - }else { - ret =__copy_from_user (&fpu->state.xsave, buf_fx, state_size); - -if (!ret && state_size > offsetof(struct xregs_state , header)) - ret =validate_user_xstate_header (&fpu->state.xsave.header); - } + ret =copy_user_to_xstate (&fpu->state.xsave, buf_fx);if (ret) goto err_out;
Greg Kroah-Hartman
maintainerPATCH 145/178 x86/fpu: Invalidate FPU state after a failed XRSTOR from a user buffer
In reply to Greg Kroah-HartmanFrom: Andy Lutomirski <[email protected]>
commit d8778e393afa421f1f117471144f8ce6deb6953a upstream.
Both Intel and AMD consider it to be architecturally valid for XRSTOR to fail with #PF but nonetheless change the register state. The actual conditions under which this might occur are unclear [1], but it seems plausible that this might be triggered if one sibling thread unmaps a page and invalidates the shared TLB while another sibling thread is executing XRSTOR on the page in question.
__fpu__restore_sig() can execute XRSTOR while the hardware registers are preserved on behalf of a different victim task (using the fpu_fpregs_owner_ctx mechanism), and, in theory, XRSTOR could fail but modify the registers.
If this happens, then there is a window in which __fpu__restore_sig() could schedule out and the victim task could schedule back in without reloading its own FPU registers. This would result in part of the FPU state that __fpu__restore_sig() was attempting to load leaking into the victim task's user-visible state.
Invalidate preserved FPU registers on XRSTOR failure to prevent this situation from corrupting any state.
[1] Frequent readers of the errata lists might imagine "complex microarchitectural conditions".
--- arch/x86/kernel/fpu/signal.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
arch/x86/kernel/fpu/signal.c +19 -0
@@ -369,6 +369,25 @@ static int __fpu__restore_sig(void __usefpregs_unlock ();return 0 ; } + +/* +* The above did an FPU restore operation, restricted to +* the user portion of the registers, and failed, but the +* microcode might have modified the FPU registers +* nevertheless. +* +* If the FPU registers do not belong to current, then +* invalidate the FPU register state otherwise the task might +* preempt current and return to user space with corrupted +* FPU registers. +* +* In case current owns the FPU registers then no further +* action is required. The fixup below will handle it +* correctly. +*/ +if (test_thread_flag (TIF_NEED_FPU_LOAD )) +__cpu_invalidate_fpregs_state (); +fpregs_unlock (); }else {/*
Greg Kroah-Hartman
maintainerPATCH 146/178 x86/fpu: Reset state for all signal restore failures
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
commit efa165504943f2128d50f63de0c02faf6dcceb0d upstream.
If access_ok() or fpregs_soft_set() fails in __fpu__restore_sig() then the function just returns but does not clear the FPU state as it does for all other fatal failures.
Clear the FPU state for these failures as well.
--- arch/x86/kernel/fpu/signal.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
arch/x86/kernel/fpu/signal.c +15 -11
@@ -307,13 +307,17 @@ static int __fpu__restore_sig(void __usereturn 0 ; } -if (!access_ok (buf, size)) -return -EACCES ; +if (!access_ok (buf, size)) { + ret = -EACCES ; + goto out; + } -if (!static_cpu_has (X86_FEATURE_FPU )) -return fpregs_soft_set (current,NULL , -0 ,sizeof (struct user_i387_ia32_struct ), -NULL , buf) !=0 ; +if (!static_cpu_has (X86_FEATURE_FPU )) { + ret =fpregs_soft_set (current,NULL ,0 , +sizeof (struct user_i387_ia32_struct ), +NULL , buf); + goto out; + }if (use_xsave ()) {struct _fpx_sw_bytes fx_sw_user;
@@ -396,7 +400,7 @@ static int __fpu__restore_sig(void __use*/ ret =__copy_from_user (&env, buf,sizeof (env));if (ret) - goto err_out; + goto out; envp = &env; }
@@ -426,7 +430,7 @@ static int __fpu__restore_sig(void __use ret =copy_user_to_xstate (&fpu->state.xsave, buf_fx);if (ret) - goto err_out; + goto out;sanitize_restored_user_xstate (&fpu->state, envp, user_xfeatures, fx_only);
@@ -446,7 +450,7 @@ static int __fpu__restore_sig(void __use ret =__copy_from_user (&fpu->state.fxsave, buf_fx, state_size);if (ret) { ret = -EFAULT ; - goto err_out; + goto out; } sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures,
@@ -464,7 +468,7 @@ static int __fpu__restore_sig(void __use }else { ret =__copy_from_user (&fpu->state.fsave, buf_fx, state_size);if (ret) - goto err_out; + goto out;fpregs_lock (); ret =copy_kernel_to_fregs_err (&fpu->state.fsave);
@@ -475,7 +479,7 @@ static int __fpu__restore_sig(void __usefpregs_deactivate (fpu);fpregs_unlock (); -err_out: +out:if (ret)fpu__clear_user_states (fpu);return ret;
Greg Kroah-Hartman
maintainerPATCH 147/178 powerpc/perf: Fix crash in perf_instruction_pointer() when ppmu is not set
In reply to Greg Kroah-HartmanFrom: Athira Rajeev <[email protected]>
commit 60b7ed54a41b550d50caf7f2418db4a7e75b5bdc upstream.
On systems without any specific PMU driver support registered, running perf record causes Oops.
The relevant portion from call trace:
BUG: Kernel NULL pointer dereference on read at 0x00000040
Faulting instruction address: 0xc0021f0c
Oops: Kernel access of bad area, sig: 11 [#1]
BE PAGE_SIZE=4K PREEMPT CMPCPRO
SAF3000 DIE NOTIFICATION
CPU: 0 PID: 442 Comm: null_syscall Not tainted 5.13.0-rc6-s3k-dev-01645-g7649ee3d2957 #5164
NIP: c0021f0c LR: c00e8ad8 CTR: c00d8a5c
NIP perf_instruction_pointer+0x10/0x60
LR perf_prepare_sample+0x344/0x674
Call Trace:
perf_prepare_sample+0x7c/0x674 (unreliable)
perf_event_output_forward+0x3c/0x94
__perf_event_overflow+0x74/0x14c
perf_swevent_hrtimer+0xf8/0x170
__hrtimer_run_queues.constprop.0+0x160/0x318
hrtimer_interrupt+0x148/0x3b0
timer_interrupt+0xc4/0x22c
Decrementer_virt+0xb8/0xbcDuring perf record session, perf_instruction_pointer() is called to capture the sample IP. This function in core-book3s accesses ppmu->flags. If a platform specific PMU driver is not registered, ppmu is set to NULL and accessing its members results in a crash. Fix this crash by checking if ppmu is set.
--- arch/powerpc/perf/core-book3s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/perf/core-book3s.c +1 -1
@@ -2242,7 +2242,7 @@ unsigned long perf_instruction_pointer(sbool use_siar =regs_use_siar (regs);unsigned long siar =mfspr (SPRN_SIAR ); -if (ppmu->flags &PPMU_P10_DD1 ) { +if (ppmu && (ppmu->flags &PPMU_P10_DD1 )) {if (siar)return siar;else
Greg Kroah-Hartman
maintainerPATCH 148/178 Makefile: lto: Pass -warn-stack-size only on LLD < 13.0.0
In reply to Greg Kroah-HartmanFrom: Tor Vic <[email protected]>
commit 0236526d76b87c1dc2cbe3eb31ae29be5b0ca151 upstream.
Since LLVM commit fc018eb, the '-warn-stack-size' flag has been dropped [1], leading to the following error message when building with Clang-13 and LLD-13:
ld.lld: error: -plugin-opt=-: ld.lld: Unknown command line argument
'-warn-stack-size=2048'. Try: 'ld.lld --help'
ld.lld: Did you mean '--asan-stack=2048'?In the same way as with commit 2398ce80152a ("x86, lto: Pass -stack-alignment only on LLD < 13.0.0") , make '-warn-stack-size' conditional on LLD < 13.0.0.
[1] https://reviews.llvm.org/D103928
--- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
Makefile +4 -1
@@ -913,11 +913,14 @@ CC_FLAGS_LTO += -fvisibility=hidden # Limit inlining across translation units to reduce binary size KBUILD_LDFLAGS += -mllvm -import-instr-limit=5 -# Check for frame size exceeding threshold during prolog/epilog insertion. +# Check for frame size exceeding threshold during prolog/epilog insertion +# when using lld < 13.0.0. ifneq ($(CONFIG_FRAME_WARN),0) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) KBUILD_LDFLAGS += -plugin-opt=-warn-stack-size=$(CONFIG_FRAME_WARN) endif endif +endif ifdef CONFIG_LTO KBUILD_CFLAGS += -fno-lto $(CC_FLAGS_LTO)
Greg Kroah-Hartman
maintainerPATCH 149/178 crash_core, vmcoreinfo: append SECTION_SIZE_BITS to vmcoreinfo
In reply to Greg Kroah-HartmanFrom: Pingfan Liu <[email protected]>
commit 4f5aecdff25f59fb5ea456d5152a913906ecf287 upstream.
As mentioned in kernel commit 1d50e5d0c505 ("crash_core, vmcoreinfo:
Append 'MAX_PHYSMEM_BITS' to vmcoreinfo"), SECTION_SIZE_BITS in the formula:
#define SECTIONS_SHIFT (MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
Besides SECTIONS_SHIFT, SECTION_SIZE_BITS is also used to calculate PAGES_PER_SECTION in makedumpfile just like kernel.
Unfortunately, this arch-dependent macro SECTION_SIZE_BITS changes, e.g. recently in kernel commit f0b13ee23241 ("arm64/sparsemem: reduce SECTION_SIZE_BITS"). But user space wants a stable interface to get this info. Such info is impossible to be deduced from a crashdump vmcore. Hence append SECTION_SIZE_BITS to vmcoreinfo.
--- kernel/crash_core.c | 1 + 1 file changed, 1 insertion(+)
kernel/crash_core.c +1 -0
@@ -464,6 +464,7 @@ static int __init crash_save_vmcoreinfo_VMCOREINFO_LENGTH (mem_section,NR_SECTION_ROOTS );VMCOREINFO_STRUCT_SIZE (mem_section);VMCOREINFO_OFFSET (mem_section, section_mem_map); +VMCOREINFO_NUMBER (SECTION_SIZE_BITS );VMCOREINFO_NUMBER (MAX_PHYSMEM_BITS );#endif VMCOREINFO_STRUCT_SIZE (page);
Greg Kroah-Hartman
maintainerPATCH 150/178 dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc
In reply to Greg Kroah-HartmanFrom: Bumyong Lee <[email protected]>
commit 4ad5dd2d7876d79507a20f026507d1a93b8fff10 upstream.
flags varible which is the input parameter of pl330_prep_dma_cyclic() should not be used by spinlock_irq[save/restore] function.
--- drivers/dma/pl330.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/dma/pl330.c +4 -2
@@ -2694,13 +2694,15 @@ static struct dma_async_tx_descriptor *pfor (i =0 ; i < len / period_len; i++) { desc =pl330_get_desc (pch);if (!desc) { +unsigned long iflags; +dev_err (pch->dmac->ddma.dev,"%s:%d Unable to fetch desc\n" , __func__, __LINE__);if (!first)return NULL ; -spin_lock_irqsave (&pl330->pool_lock, flags); +spin_lock_irqsave (&pl330->pool_lock, iflags);while (!list_empty (&first->node)) { desc = list_entry(first->node.next,
@@ -2710,7 +2712,7 @@ static struct dma_async_tx_descriptor *plist_move_tail (&first->node, &pl330->desc_pool); -spin_unlock_irqrestore (&pl330->pool_lock, flags); +spin_unlock_irqrestore (&pl330->pool_lock, iflags);return NULL ; }
Greg Kroah-Hartman
maintainerPATCH 151/178 mac80211: fix deadlock in AP/VLAN handling
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit d5befb224edbe53056c2c18999d630dafb4a08b9 upstream.
Syzbot reports that when you have AP_VLAN interfaces that are up and close the AP interface they belong to, we get a deadlock. No surprise - since we dev_close() them with the wiphy mutex held, which goes back into the netdev notifier in cfg80211 and tries to acquire the wiphy mutex there.
To fix this, we need to do two things:
1) prevent changing iftype while AP_VLANs are up, we can't easily fix this case since cfg80211 already calls us with the wiphy mutex held, but change_interface() is relatively rare in drivers anyway, so changing iftype isn't used much (and userspace has to fall back to down/change/up anyway)
2) pull the dev_close() loop over VLANs out of the wiphy mutex section in the normal stop case
--- net/mac80211/iface.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
net/mac80211/iface.c +12 -7
@@ -475,14 +475,7 @@ static void ieee80211_do_stop(struct iee GFP_KERNEL); } -/* APs need special treatment */ if (sdata->vif.type ==NL80211_IFTYPE_AP ) { -struct ieee80211_sub_if_data *vlan, *tmpsdata; - -/* down all dependent devices, that is VLANs */ -list_for_each_entry_safe (vlan, tmpsdata, &sdata->u.ap.vlans, - u.vlan.list) -dev_close (vlan->dev);WARN_ON (!list_empty (&sdata->u.ap.vlans)); }else if (sdata->vif.type ==NL80211_IFTYPE_AP_VLAN ) {/* remove all packets in parent bc_buf pointing to this dev */
@@ -640,6 +633,15 @@ static int ieee80211_stop(struct net_dev {struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +/* close all dependent VLAN interfaces before locking wiphy */ +if (sdata->vif.type ==NL80211_IFTYPE_AP ) { +struct ieee80211_sub_if_data *vlan, *tmpsdata; + +list_for_each_entry_safe (vlan, tmpsdata, &sdata->u.ap.vlans, + u.vlan.list) +dev_close (vlan->dev); + } +wiphy_lock (sdata->local->hw.wiphy);ieee80211_do_stop (sdata, true);wiphy_unlock (sdata->local->hw.wiphy);
@@ -1589,6 +1591,9 @@ static int ieee80211_runtime_change_iftyswitch (sdata->vif.type) {case NL80211_IFTYPE_AP : +if (!list_empty (&sdata->u.ap.vlans)) +return -EBUSY ; +break ;case NL80211_IFTYPE_STATION :case NL80211_IFTYPE_ADHOC :case NL80211_IFTYPE_OCB :
Greg Kroah-Hartman
maintainerPATCH 152/178 mac80211: Fix NULL ptr deref for injected rate info
In reply to Greg Kroah-HartmanFrom: Mathy Vanhoef <[email protected]>
commit bddc0c411a45d3718ac535a070f349be8eca8d48 upstream.
The commit cb17ed29a7a5 ("mac80211: parse radiotap header when selecting Tx queue") moved the code to validate the radiotap header from ieee80211_monitor_start_xmit to ieee80211_parse_tx_radiotap. This made is possible to share more code with the new Tx queue selection code for injected frames. But at the same time, it now required the call of ieee80211_parse_tx_radiotap at the beginning of functions which wanted to handle the radiotap header. And this broke the rate parser for radiotap header parser.
The radiotap parser for rates is operating most of the time only on the data in the actual radiotap header. But for the 802.11a/b/g rates, it must also know the selected band from the chandef information. But this information is only written to the ieee80211_tx_info at the end of the ieee80211_monitor_start_xmit - long after ieee80211_parse_tx_radiotap was already called. The info->band information was therefore always 0 (NL80211_BAND_2GHZ) when the parser code tried to access it.
For a 5GHz only device, injecting a frame with 802.11a rates would cause a NULL pointer dereference because local->hw.wiphy->bands[NL80211_BAND_2GHZ] would most likely have been NULL when the radiotap parser searched for the correct rate index of the driver.
--- include/net/mac80211.h | 7 +++++- net/mac80211/tx.c | 52 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 17 deletions(-)
include/net/mac80211.h +6 -1
@@ -6388,7 +6388,12 @@ bool ieee80211_tx_prepare_skb(struct iee/** * ieee80211_parse_tx_radiotap - Sanity-check and parse the radiotap header -* of injected frames +* of injected frames. +* +* To accurately parse and take into account rate and retransmission fields, +* you must initialize the chandef field in the ieee80211_tx_info structure +* of the skb before calling this function. +* * @skb: packet injected by userspace * @dev: the &struct device of this 802.11 device */
net/mac80211/tx.c +36 -16
94 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 153/178 mac80211: fix reset debugfs locking
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit adaed1b9daf5a045be71e923e04b5069d2bee664 upstream.
cfg80211 now calls suspend/resume with the wiphy lock held, and while there's a problem with that needing to be fixed, we should do the same in debugfs.
--- net/mac80211/debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/mac80211/debugfs.c +3 -1
@@ -4,7 +4,7 @@* * Copyright 2007 Johannes Berg <[email protected]> * Copyright 2013-2014 Intel Mobile Communications GmbH -* Copyright (C) 2018 - 2019 Intel Corporation +* Copyright (C) 2018 - 2019, 2021 Intel Corporation */ #include <linux/debugfs.h>
@@ -389,8 +389,10 @@ static ssize_t reset_write(struct file *struct ieee80211_local *local = file->private_data;rtnl_lock (); +wiphy_lock (local->hw.wiphy);__ieee80211_suspend (&local->hw,NULL );__ieee80211_resume (&local->hw); +wiphy_unlock (local->hw.wiphy);rtnl_unlock ();return count;
Greg Kroah-Hartman
maintainerPATCH 154/178 cfg80211: fix phy80211 symlink creation
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 43076c1e074359f11c85d7d1b85ede1bbb8ee6b9 upstream.
When I moved around the code here, I neglected that we could still call register_netdev() or similar without the wiphy mutex held, which then calls cfg80211_register_wdev() - that's also done from cfg80211_register_netdevice(), but the phy80211 symlink creation was only there. Now, the symlink isn't needed for a *pure* wdev, but a netdev not registered via cfg80211_register_wdev() should still have the symlink, so move the creation to the right place.
--- net/wireless/core.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
net/wireless/core.c +5 -8
@@ -1339,6 +1339,11 @@ void cfg80211_register_wdev(struct cfg80 rdev->devlist_generation++; wdev->registered = true; +if (wdev->netdev && +sysfs_create_link (&wdev->netdev->dev.kobj, &rdev->wiphy.dev.kobj, +"phy80211" )) +pr_err ("failed to add phy80211 symlink to netdev!\n" ); +nl80211_notify_iface (rdev, wdev,NL80211_CMD_NEW_INTERFACE ); }
@@ -1364,14 +1369,6 @@ int cfg80211_register_netdevice(struct nif (ret) goto out; -if (sysfs_create_link (&dev->dev.kobj, &rdev->wiphy.dev.kobj, -"phy80211" )) { -pr_err ("failed to add phy80211 symlink to netdev!\n" ); -unregister_netdevice (dev); - ret = -EINVAL ; - goto out; - } -cfg80211_register_wdev (rdev, wdev); ret =0 ; out:
Greg Kroah-Hartman
maintainerPATCH 155/178 cfg80211: shut down interfaces on failed resume
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit 65bec836da8394b1d56bdec2c478dcac21cf12a4 upstream.
If resume fails, we should shut down all interfaces as the hardware is probably dead. This was/is already done now in mac80211, but we need to change that due to locking issues, so move it here and do it without the wiphy lock held.
--- net/wireless/sysfs.c | 4 ++++ 1 file changed, 4 insertions(+)
net/wireless/sysfs.c +4 -0
@@ -133,6 +133,10 @@ static int wiphy_resume(struct device *dif (rdev->wiphy.registered && rdev->ops->resume) ret =rdev_resume (rdev);wiphy_unlock (&rdev->wiphy); + +if (ret) +cfg80211_shutdown_all_interfaces (&rdev->wiphy); +rtnl_unlock ();return ret;
Greg Kroah-Hartman
maintainerPATCH 156/178 mac80211: move interface shutdown out of wiphy lock
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit f5baf287f5da5641099ad5c809b3b4ebfc08506d upstream.
When reconfiguration fails, we shut down everything, but we cannot call cfg80211_shutdown_all_interfaces() with the wiphy mutex held. Since cfg80211 now calls it on resume errors, we only need to do likewise for where we call reconfig (whether directly or indirectly), but not under the wiphy lock.
--- net/mac80211/debugfs.c | 7 ++++++- net/mac80211/main.c | 7 ++++++- net/mac80211/util.c | 2 -- 3 files changed, 12 insertions(+), 4 deletions(-)
net/mac80211/debugfs.c +6 -1
@@ -387,12 +387,17 @@ static ssize_t reset_write(struct file * size_t count, loff_t *ppos) { struct ieee80211_local *local = file->private_data; +int ret;rtnl_lock ();wiphy_lock (local->hw.wiphy);__ieee80211_suspend (&local->hw,NULL ); -__ieee80211_resume (&local->hw); + ret =__ieee80211_resume (&local->hw);wiphy_unlock (local->hw.wiphy); + +if (ret) +cfg80211_shutdown_all_interfaces (local->hw.wiphy); +rtnl_unlock ();return count;
net/mac80211/main.c +6 -1
@@ -252,6 +252,7 @@ static void ieee80211_restart_work(strucstruct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work);struct ieee80211_sub_if_data *sdata; +int ret;/* wait for scan work complete */ flush_workqueue (local->workqueue);
@@ -294,8 +295,12 @@ static void ieee80211_restart_work(struc/* wait for all packet processing to be done */ synchronize_net (); -ieee80211_reconfig (local); + ret =ieee80211_reconfig (local);wiphy_unlock (local->hw.wiphy); + +if (ret) +cfg80211_shutdown_all_interfaces (local->hw.wiphy); +rtnl_unlock (); }
net/mac80211/util.c +0 -2
@@ -2186,8 +2186,6 @@ static void ieee80211_handle_reconfig_falist_for_each_entry (ctx, &local->chanctx_list, list) ctx->driver_present = false;mutex_unlock (&local->chanctx_mtx); - -cfg80211_shutdown_all_interfaces (local->hw.wiphy); } static void ieee80211_assign_chanctx(struct ieee80211_local *local,
Greg Kroah-Hartman
maintainerPATCH 157/178 mac80211: minstrel_ht: fix sample time check
In reply to Greg Kroah-HartmanFrom: Felix Fietkau <[email protected]>
commit 1236af327af476731aa548dfcbbefb1a3ec6726a upstream.
We need to skip sampling if the next sample time is after jiffies, not before. This patch fixes an issue where in some cases only very little sampling (or none at all) is performed, leading to really bad data rates
--- net/mac80211/rc80211_minstrel_ht.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/rc80211_minstrel_ht.c +1 -1
@@ -1516,7 +1516,7 @@ minstrel_ht_get_rate(void *priv, struct (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) return; -if (time_is_before_jiffies (mi->sample_time)) +if (time_is_after_jiffies (mi->sample_time))return ; mi->sample_time = jiffies +MINSTREL_SAMPLE_INTERVAL ;
Greg Kroah-Hartman
maintainerPATCH 158/178 cfg80211: make certificate generation more robust
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
commit b5642479b0f7168fe16d156913533fe65ab4f8d5 upstream.
If all net/wireless/certs/*.hex files are deleted, the build will hang at this point since the 'cat' command will have no arguments. Do "echo | cat - ..." so that even if the "..." part is empty, the whole thing won't hang.
--- net/wireless/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/wireless/Makefile +1 -1
@@ -28,7 +28,7 @@ $(obj)/shipped-certs.c: $(wildcard $(src @$(kecho) " GEN $@" @(echo '#include "reg.h"'; \ echo 'const u8 shipped_regdb_certs[] = {'; \ - cat $^ ; \ + echo | cat - $^ ; \ echo '};'; \ echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \ ) > $@
Greg Kroah-Hartman
maintainerPATCH 159/178 cfg80211: avoid double free of PMSR request
In reply to Greg Kroah-HartmanFrom: Avraham Stern <[email protected]>
commit 0288e5e16a2e18f0b7e61a2b70d9037fc6e4abeb upstream.
If cfg80211_pmsr_process_abort() moves all the PMSR requests that need to be freed into a local list before aborting and freeing them. As a result, it is possible that cfg80211_pmsr_complete() will run in parallel and free the same PMSR request.
Fix it by freeing the request in cfg80211_pmsr_complete() only if it is still in the original pmsr list.
--- net/wireless/pmsr.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
net/wireless/pmsr.c +14 -2
@@ -324,6 +324,7 @@ void cfg80211_pmsr_complete(struct wirel gfp_t gfp) {struct cfg80211_registered_device *rdev =wiphy_to_rdev (wdev->wiphy); +struct cfg80211_pmsr_request *tmp, *prev, *to_free =NULL ;struct sk_buff *msg;void *hdr;
@@ -354,9 +355,20 @@ free_msg:nlmsg_free (msg); free_request:spin_lock_bh (&wdev->pmsr_lock); -list_del (&req->list); +/* +* cfg80211_pmsr_process_abort() may have already moved this request +* to the free list, and will free it later. In this case, don't free +* it here. +*/ +list_for_each_entry_safe (tmp, prev, &wdev->pmsr_list, list) { +if (tmp == req) { +list_del (&req->list); + to_free = req; +break ; + } + }spin_unlock_bh (&wdev->pmsr_lock); -kfree (req); +kfree (to_free); }EXPORT_SYMBOL_GPL (cfg80211_pmsr_complete);
Greg Kroah-Hartman
maintainerPATCH 160/178 drm/amdgpu/gfx10: enlarge CP_MEC_DOORBELL_RANGE_UPPER to cover full doorbell.
In reply to Greg Kroah-HartmanFrom: Yifan Zhang <[email protected]>
commit 1c0b0efd148d5b24c4932ddb3fa03c8edd6097b3 upstream.
If GC has entered CGPG, ringing doorbell > first page doesn't wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround this issue.
--- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +5 -1
@@ -6769,8 +6769,12 @@ static int gfx_v10_0_kiq_init_register(sif (ring->use_doorbell) {WREG32_SOC15 (GC ,0 , mmCP_MEC_DOORBELL_RANGE_LOWER, (adev->doorbell_index.kiq *2 ) <<2 ); +/* If GC has entered CGPG, ringing doorbell > first page doesn't +* wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround +* this issue. +*/ WREG32_SOC15 (GC ,0 , mmCP_MEC_DOORBELL_RANGE_UPPER, - (adev->doorbell_index.userqueue_end *2 ) <<2 ); + (adev->doorbell.size -4 )); } WREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL,
Greg Kroah-Hartman
maintainerPATCH 161/178 drm/amdgpu/gfx9: fix the doorbell missing when in CGPG issue.
In reply to Greg Kroah-HartmanFrom: Yifan Zhang <[email protected]>
commit 4cbbe34807938e6e494e535a68d5ff64edac3f20 upstream.
If GC has entered CGPG, ringing doorbell > first page doesn't wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround this issue.
--- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +5 -1
@@ -3623,8 +3623,12 @@ static int gfx_v9_0_kiq_init_register(stif (ring->use_doorbell) {WREG32_SOC15 (GC ,0 , mmCP_MEC_DOORBELL_RANGE_LOWER, (adev->doorbell_index.kiq *2 ) <<2 ); +/* If GC has entered CGPG, ringing doorbell > first page doesn't +* wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to workaround +* this issue. +*/ WREG32_SOC15 (GC ,0 , mmCP_MEC_DOORBELL_RANGE_UPPER, - (adev->doorbell_index.userqueue_end *2 ) <<2 ); + (adev->doorbell.size -4 )); } WREG32_SOC15_RLC(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL,
Greg Kroah-Hartman
maintainerPATCH 162/178 net: ll_temac: Make sure to free skb when it is completely used
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
commit 6aa32217a9a446275440ee8724b1ecaf1838df47 upstream.
With the skb pointer piggy-backed on the TX BD, we have a simple and efficient way to free the skb buffer when the frame has been transmitted. But in order to avoid freeing the skb while there are still fragments from the skb in use, we need to piggy-back on the TX BD of the skb, not the first.
Without this, we are doing use-after-free on the DMA side, when the first BD of a multi TX BD packet is seen as completed in xmit_done, and the remaining BDs are still being processed.
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +5 -1
@@ -876,7 +876,6 @@ temac_start_xmit(struct sk_buff *skb, streturn NETDEV_TX_OK ; } cur_p->phys =cpu_to_be32 (skb_dma_addr); -ptr_to_txbd ((void *)skb, cur_p);for (ii =0 ; ii < num_frag; ii++) {if (++lp->tx_bd_tail >= lp->tx_bd_num)
@@ -915,6 +914,11 @@ temac_start_xmit(struct sk_buff *skb, st } cur_p->app0 |=cpu_to_be32 (STS_CTRL_APP0_EOP ); +/* Mark last fragment with skb address, so it can be consumed +* in temac_start_xmit_done() +*/ +ptr_to_txbd ((void *)skb, cur_p); + tail_p = lp->tx_bd_p +sizeof (*lp->tx_bd_v) * lp->tx_bd_tail; lp->tx_bd_tail++;if (lp->tx_bd_tail >= lp->tx_bd_num)
Greg Kroah-Hartman
maintainerPATCH 163/178 net: ll_temac: Fix TX BD buffer overwrite
In reply to Greg Kroah-HartmanFrom: Esben Haabendal <[email protected]>
commit c364df2489b8ef2f5e3159b1dff1ff1fdb16040d upstream.
Just as the initial check, we need to ensure num_frag+1 buffers available, as that is the number of buffers we are going to use.
This fixes a buffer overflow, which might be seen during heavy network load. Complete lockup of TEMAC was reproducible within about 10 minutes of a particular load.
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +1 -1
@@ -849,7 +849,7 @@ temac_start_xmit(struct sk_buff *skb, stsmp_mb ();/* Space might have just been freed - check again */ -if (temac_check_tx_bd_space (lp, num_frag)) +if (temac_check_tx_bd_space (lp, num_frag +1 ))return NETDEV_TX_BUSY ;netif_wake_queue (ndev);
Greg Kroah-Hartman
maintainerPATCH 164/178 net: bridge: fix vlan tunnel dst null pointer dereference
In reply to Greg Kroah-HartmanFrom: Nikolay Aleksandrov <[email protected]>
commit 58e2071742e38f29f051b709a5cca014ba51166f upstream.
This patch fixes a tunnel_dst null pointer dereference due to lockless access in the tunnel egress path. When deleting a vlan tunnel the tunnel_dst pointer is set to NULL without waiting a grace period (i.e. while it's still usable) and packets egressing are dereferencing it without checking. Use READ/WRITE_ONCE to annotate the lockless use of tunnel_id, use RCU for accessing tunnel_dst and make sure it is read only once and checked in the egress path. The dst is already properly RCU protected so we don't need to do anything fancy than to make sure tunnel_id and tunnel_dst are read only once and checked in the egress path.
--- net/bridge/br_private.h | 4 ++-- net/bridge/br_vlan_tunnel.c | 38 ++++++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 16 deletions(-)
net/bridge/br_private.h +2 -2
@@ -90,8 +90,8 @@ struct bridge_mcast_stats {#endif struct br_tunnel_info { -__be64 tunnel_id; -struct metadata_dst *tunnel_dst; +__be64 tunnel_id; +struct metadata_dst __rcu *tunnel_dst; };/* private vlan flags */
net/bridge/br_vlan_tunnel.c +24 -14
@@ -41,26 +41,33 @@ static struct net_bridge_vlan *br_vlan_t br_vlan_tunnel_rht_params); } +static void vlan_tunnel_info_release (struct net_bridge_vlan *vlan) +{ +struct metadata_dst *tdst =rtnl_dereference (vlan->tinfo.tunnel_dst); + +WRITE_ONCE (vlan->tinfo.tunnel_id,0 ); +RCU_INIT_POINTER (vlan->tinfo.tunnel_dst,NULL ); +dst_release (&tdst->dst); +} +void vlan_tunnel_info_del (struct net_bridge_vlan_group *vg,struct net_bridge_vlan *vlan) { -if (!vlan->tinfo.tunnel_dst) +if (!rcu_access_pointer (vlan->tinfo.tunnel_dst))return ;rhashtable_remove_fast (&vg->tunnel_hash, &vlan->tnode, br_vlan_tunnel_rht_params); - vlan->tinfo.tunnel_id =0 ; -dst_release (&vlan->tinfo.tunnel_dst->dst); - vlan->tinfo.tunnel_dst =NULL ; +vlan_tunnel_info_release (vlan); }static int __vlan_tunnel_info_add (struct net_bridge_vlan_group *vg,struct net_bridge_vlan *vlan,u32 tun_id) { -struct metadata_dst *metadata =NULL ; +struct metadata_dst *metadata =rtnl_dereference (vlan->tinfo.tunnel_dst);__be64 key =key32_to_tunnel_id (cpu_to_be32 (tun_id));int err; -if (vlan->tinfo.tunnel_dst) +if (metadata)return -EEXIST ; metadata = __ip_tun_set_dst(0, 0, 0, 0, 0, TUNNEL_KEY,
@@ -69,8 +76,8 @@ static int __vlan_tunnel_info_add(structreturn -EINVAL ; metadata->u.tun_info.mode |=IP_TUNNEL_INFO_TX |IP_TUNNEL_INFO_BRIDGE ; - vlan->tinfo.tunnel_dst = metadata; - vlan->tinfo.tunnel_id = key; +rcu_assign_pointer (vlan->tinfo.tunnel_dst, metadata); +WRITE_ONCE (vlan->tinfo.tunnel_id, key); err =rhashtable_lookup_insert_fast (&vg->tunnel_hash, &vlan->tnode, br_vlan_tunnel_rht_params);
@@ -79,9 +86,7 @@ static int __vlan_tunnel_info_add(structreturn 0 ; out: -dst_release (&vlan->tinfo.tunnel_dst->dst); - vlan->tinfo.tunnel_dst =NULL ; - vlan->tinfo.tunnel_id =0 ; +vlan_tunnel_info_release (vlan);return err; }
@@ -182,12 +187,15 @@ int br_handle_ingress_vlan_tunnel(structint br_handle_egress_vlan_tunnel (struct sk_buff *skb,struct net_bridge_vlan *vlan) { +struct metadata_dst *tunnel_dst; +__be64 tunnel_id;int err; -if (!vlan || !vlan->tinfo.tunnel_id) +if (!vlan)return 0 ; -if (unlikely (!skb_vlan_tag_present (skb))) + tunnel_id =READ_ONCE (vlan->tinfo.tunnel_id); +if (!tunnel_id ||unlikely (!skb_vlan_tag_present (skb)))return 0 ;skb_dst_drop (skb);
@@ -195,7 +203,9 @@ int br_handle_egress_vlan_tunnel(structif (err)return err; -skb_dst_set (skb,dst_clone (&vlan->tinfo.tunnel_dst->dst)); + tunnel_dst =rcu_dereference (vlan->tinfo.tunnel_dst); +if (tunnel_dst) +skb_dst_set (skb,dst_clone (&tunnel_dst->dst));return 0 ; }