5.10.226-rc1 review
Greg Kroah-Hartman
maintainercover 5.10.226-rc1 review
This is the start of the stable review cycle for the 5.10.226 release. There are 186 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 Thu, 12 Sep 2024 09:25:22 +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.10.226-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.10.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.10.226-rc1
Shakeel Butt <[email protected]>
memcg: protect concurrent access to mem_cgroup_idr
Daniel Borkmann <[email protected]>
net, sunrpc: Remap EPERM in case of connection failure in xs_tcp_setup_socket
Thomas Gleixner <[email protected]>
x86/mm: Fix PTI for i386 some more
Roland Xu <[email protected]>
rtmutex: Drop rt_mutex::wait_lock before scheduling
Seunghwan Baek <[email protected]>
mmc: cqhci: Fix checking of CQHCI_HALT state
Andy Shevchenko <[email protected]>
drm/i915/fence: Mark debug_fence_free() with __maybe_unused
Andy Shevchenko <[email protected]>
drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
Maurizio Lombardi <[email protected]>
nvmet-tcp: fix kernel crash if commands allocation fails
Jonathan Cameron <[email protected]>
arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
James Morse <[email protected]>
arm64: acpi: Move get_cpu_for_acpi_id() to a header
Jonathan Cameron <[email protected]>
ACPI: processor: Fix memory leaks in error paths of processor_add()
Jonathan Cameron <[email protected]>
ACPI: processor: Return an error if acpi_processor_get_info() fails in processor_add()
Ryusuke Konishi <[email protected]>
nilfs2: protect references to superblock parameters exposed in sysfs
Qing Wang <[email protected]>
nilfs2: replace snprintf in show functions with sysfs_emit
Peter Zijlstra <[email protected]>
perf/aux: Fix AUX buffer serialization
Sven Schnelle <[email protected]>
uprobes: Use kzalloc to allocate xol area
Daniel Lezcano <[email protected]>
clocksource/drivers/timer-of: Remove percpu irq related code
Jacky Bai <[email protected]>
clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
Jacky Bai <[email protected]>
clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
David Fernandez Gonzalez <[email protected]>
VMCI: Fix use-after-free when removing resource in vmci_resource_remove()
Naman Jain <[email protected]>
Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic
Saurabh Sengar <[email protected]>
uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind
Geert Uytterhoeven <[email protected]>
nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc
Carlos Llamas <[email protected]>
binder: fix UAF caused by offsets overwrite
Dumitru Ceclan <[email protected]>
iio: adc: ad7124: fix chip ID mismatch
Guillaume Stols <[email protected]>
iio: adc: ad7606: remove frstdata check for serial mode
Matteo Martelli <[email protected]>
iio: fix scale application in iio_convert_raw_to_processed_unlocked
David Lechner <[email protected]>
iio: buffer-dmaengine: fix releasing dma channel on error
Aleksandr Mishin <[email protected]>
staging: iio: frequency: ad9834: Validate frequency parameter value
Trond Myklebust <[email protected]>
NFSv4: Add missing rescheduling points in nfs_client_return_marked_delegations
Michael Ellerman <[email protected]>
ata: pata_macio: Use WARN instead of BUG
Jiaxun Yang <[email protected]>
MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed
Kent Overstreet <[email protected]>
lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
Stefan Wiehler <[email protected]>
of/irq: Prevent device address out-of-bounds read in interrupt map walk
Phillip Lougher <[email protected]>
Squashfs: sanity check symbolic link size
Oliver Neukum <[email protected]>
usbnet: ipheth: race between ipheth_close and error handling
Dmitry Torokhov <[email protected]>
Input: uinput - reject requests with unreasonable number of slots
Camila Alvarez <[email protected]>
HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
Heiko Carstens <[email protected]>
s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
David Sterba <[email protected]>
btrfs: initialize location to fix -Wmaybe-uninitialized in btrfs_lookup_dentry()
Zenghui Yu <[email protected]>
kselftests: dmabuf-heaps: Ensure the driver name is null-terminated
Vladimir Oltean <[email protected]>
net: dpaa: avoid on-stack arrays of NR_CPUS elements
Dan Williams <[email protected]>
PCI: Add missing bridge lock to pci_bus_lock()
Josef Bacik <[email protected]>
btrfs: clean up our handling of refs == 0 in snapshot delete
Josef Bacik <[email protected]>
btrfs: replace BUG_ON with ASSERT in walk_down_proc()
Zqiang <[email protected]>
smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
Sascha Hauer <[email protected]>
wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
Andreas Ziegler <[email protected]>
libbpf: Add NULL checks to bpf_object__{prev_map,next_map}Guenter Roeck <[email protected]>
hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
Guenter Roeck <[email protected]>
hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
Guenter Roeck <[email protected]>
hwmon: (lm95234) Fix underflows seen when writing limit attributes
Guenter Roeck <[email protected]>
hwmon: (adc128d818) Fix underflows seen when writing limit attributes
Krishna Kumar <[email protected]>
pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
Zijun Hu <[email protected]>
devres: Initialize an uninitialized struct member
Johannes Berg <[email protected]>
um: line: always fill *error_out in setup_one_line()
Waiman Long <[email protected]>
cgroup: Protect css->cgroup write under css_set_lock
Jacob Pan <[email protected]>
iommu/vt-d: Handle volatile descriptor status read
Benjamin Marzinski <[email protected]>
dm init: Handle minors larger than 255
Amadeusz Sławiński <[email protected]>
ASoC: topology: Properly initialize soc_enum values
Pawel Dembicki <[email protected]>
net: dsa: vsc73xx: fix possible subblocks range of CAPT block
Jonas Gorski <[email protected]>
net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
Kuniyuki Iwashima <[email protected]>
fou: Fix null-ptr-deref in GRO.
Eric Dumazet <[email protected]>
gro: remove rcu_read_lock/rcu_read_unlock from gro_complete handlers
Eric Dumazet <[email protected]>
gro: remove rcu_read_lock/rcu_read_unlock from gro_receive handlers
Eric Dumazet <[email protected]>
fou: remove sparse errors
Guillaume Nault <[email protected]>
bareudp: Fix device stats updates.
Oliver Neukum <[email protected]>
usbnet: modern method to get random MAC
Jakub Kicinski <[email protected]>
net: usb: don't write directly to netdev->dev_addr
Len Baker <[email protected]>
drivers/net/usb: Remove all strcpy() uses
Dan Carpenter <[email protected]>
igc: Unlock on error in igc_io_resume()
Cong Wang <[email protected]>
tcp_bpf: fix return value of tcp_bpf_sendmsg()
Aleksandr Mishin <[email protected]>
platform/x86: dell-smbios: Fix error path in dell_smbios_init()
Chuck Lever <[email protected]>
svcrdma: Catch another Reply chunk overflow case
Daiwei Li <[email protected]>
igb: Fix not clearing TimeSync interrupts for 82580
Kuniyuki Iwashima <[email protected]>
can: bcm: Remove proc entry when dev is unregistered.
Jules Irenge <[email protected]>
pcmcia: Use resource_size function on resource object
Chen Ni <[email protected]>
media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
Kishon Vijay Abraham I <[email protected]>
PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
Hans Verkuil <[email protected]>
media: vivid: don't set HDMI TX controls if there are no HDMI outputs
Shantanu Goel <[email protected]>
usb: uas: set host status byte on data completion error
Arend van Spriel <[email protected]>
wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
Andy Shevchenko <[email protected]>
leds: spi-byte: Call of_node_put() on error path
Hans Verkuil <[email protected]>
media: vivid: fix wrong sizeimage value for mplane
Jan Kara <[email protected]>
udf: Avoid excessive partition lengths
Yunjian Wang <[email protected]>
netfilter: nf_conncount: fix wrong variable type
Jernej Skrabec <[email protected]>
iommu: sun50i: clear bypass register
Kuniyuki Iwashima <[email protected]>
af_unix: Remove put_pid()/put_cred() in copy_peercred().
Pali Rohár <[email protected]>
irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
Konstantin Andreev <[email protected]>
smack: unix sockets: fix accept()ed socket label
Takashi Iwai <[email protected]>
ALSA: hda: Add input value sanity checks to HDMI channel map controls
Josef Bacik <[email protected]>
nfsd: make svc_stat per-network namespace instead of global
Josef Bacik <[email protected]>
nfsd: remove nfsd_stats, make th_cnt a global counter
Josef Bacik <[email protected]>
nfsd: make all of the nfsd stats per-network namespace
Josef Bacik <[email protected]>
nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
Josef Bacik <[email protected]>
nfsd: rename NFSD_NET_* to NFSD_STATS_*
Josef Bacik <[email protected]>
sunrpc: use the struct net as the svc proc private
Josef Bacik <[email protected]>
sunrpc: remove ->pg_stats from svc_program
Josef Bacik <[email protected]>
sunrpc: pass in the sv_stats struct through svc_create_pooled
Josef Bacik <[email protected]>
nfsd: stop setting ->pg_stats for unused stats
Josef Bacik <[email protected]>
sunrpc: don't change ->sv_stats if it doesn't exist
Chuck Lever <[email protected]>
NFSD: Fix frame size warning in svc_export_parse()
Chuck Lever <[email protected]>
NFSD: Rewrite synopsis of nfsd_percpu_counters_init()
NeilBrown <[email protected]>
NFSD: simplify error paths in nfsd_svc()
Chuck Lever <[email protected]>
NFSD: Refactor the duplicate reply cache shrinker
Chuck Lever <[email protected]>
NFSD: Replace nfsd_prune_bucket()
Chuck Lever <[email protected]>
NFSD: Rename nfsd_reply_cache_alloc()
Chuck Lever <[email protected]>
NFSD: Refactor nfsd_reply_cache_free_locked()
Jeff Layton <[email protected]>
nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net
Jeff Layton <[email protected]>
nfsd: move reply cache initialization into nfsd startup
Matthieu Baerts (NGI0) <[email protected]>
mptcp: pm: avoid possible UaF when selecting endp
Matthieu Baerts (NGI0) <[email protected]>
mptcp: pr_debug: add missing \n at the end
Filipe Manana <[email protected]>
btrfs: fix use-after-free after failure to create a snapshot
Ryusuke Konishi <[email protected]>
nilfs2: fix state management in error path of log writing function
Ryusuke Konishi <[email protected]>
nilfs2: fix missing cleanup on rollforward recovery error
Toke Høiland-Jørgensen <[email protected]>
sched: sch_cake: fix bulk flow accounting logic for host fairness
Eric Dumazet <[email protected]>
ila: call nf_unregister_net_hooks() sooner
Zheng Yejian <[email protected]>
tracing: Avoid possible softlockup in tracing_iter_reset()
Simon Arlott <[email protected]>
can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open
Satya Priya Kakitapalli <[email protected]>
clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
Satya Priya Kakitapalli <[email protected]>
clk: qcom: clk-alpha-pll: Fix the pll post div mask
Jann Horn <[email protected]>
fuse: use unsigned type for getxattr/listxattr size truncation
Joanne Koong <[email protected]>
fuse: update stats for pages in dropped aux writeback list
Liao Chen <[email protected]>
mmc: sdhci-of-aspeed: fix module autoloading
Sam Protsenko <[email protected]>
mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
Luiz Augusto von Dentz <[email protected]>
Bluetooth: MGMT: Ignore keys being loaded with invalid type
Luiz Augusto von Dentz <[email protected]>
Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"
Ma Ke <[email protected]>
irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
Zheng Qixing <[email protected]>
ata: libata: Fix memory leak for error path in ata_host_alloc()
Maximilien Perreault <[email protected]>
ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx
Terry Cheong <[email protected]>
ALSA: hda/realtek: add patch for internal mic in Lenovo V145
Christoffer Sandberg <[email protected]>
ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius devices
robelin <[email protected]>
ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
Stephen Hemminger <[email protected]>
sch/netem: fix use after free in netem_dequeue
Connor O'Brien <[email protected]>
bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt
Richard Fitzgerald <[email protected]>
i2c: Use IS_REACHABLE() for substituting empty ACPI functions
Jan Kara <[email protected]>
ext4: handle redirtying in ext4_bio_write_page()
Jan Kara <[email protected]>
udf: Limit file size to 4TB
Nikita Kiryushin <[email protected]>
rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow
Breno Leitao <[email protected]>
virtio_net: Fix napi_skb_cache_put warning
Stanislav Fomichev <[email protected]>
net: set SOCK_RCU_FREE before inserting socket into hashtable
Connor O'Brien <[email protected]>
bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode
Bob Zhou <[email protected]>
drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
Christoph Hellwig <[email protected]>
block: initialize integrity buffer to zero before writing it to media
Ricardo Ribalda <[email protected]>
media: uvcvideo: Enforce alignment of frame and interval
Alex Hung <[email protected]>
drm/amd/display: Skip wbscl_set_scaler_filter if filter is null
Christoph Hellwig <[email protected]>
block: remove the blk_flush_integrity call in blk_integrity_unregister
Johannes Berg <[email protected]>
wifi: cfg80211: make hash table duplicates more survivable
Haoran Liu <[email protected]>
drm/meson: plane: Add error handling
Casey Schaufler <[email protected]>
smack: tcp: ipv4, fix incorrect labeling
Amir Goldstein <[email protected]>
fsnotify: clear PARENT_WATCHED flags lazily
Abhishek Pandit-Subedi <[email protected]>
usb: typec: ucsi: Fix null pointer dereference in trace
Simon Holesch <[email protected]>
usbip: Don't submit special requests twice
Shannon Nelson <[email protected]>
ionic: fix potential irq name truncation
Richard Maina <[email protected]>
hwspinlock: Introduce hwspin_lock_bust()
Aleksandr Mishin <[email protected]>
PCI: al: Check IORESOURCE_BUS existence during probe
Shahar S Matityahu <[email protected]>
wifi: iwlwifi: remove fw_running op
Jesse Zhang <[email protected]>
drm/amd/pm: check negtive return for table entries
Jesse Zhang <[email protected]>
drm/amdgpu: the warning dereferencing obj for nbio_v7_4
Ma Jun <[email protected]>
drm/amdgpu/pm: Check input value for CUSTOM profile mode setting on legacy SOCs
Leesoo Ahn <[email protected]>
apparmor: fix possible NULL pointer dereference
Michael Chen <[email protected]>
drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device
Tim Huang <[email protected]>
drm/amdgpu: fix mc_data out-of-bounds read warning
Tim Huang <[email protected]>
drm/amdgpu: fix ucode out-of-bounds read warning
Ma Jun <[email protected]>
drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
Ma Jun <[email protected]>
drm/amdgpu: Fix out-of-bounds write warning
Ma Jun <[email protected]>
drm/amdgpu/pm: Fix uninitialized variable agc_btc_response
Hersen Wu <[email protected]>
drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create
Alex Hung <[email protected]>
drm/amd/display: Check msg_id before processing transcation
Alex Hung <[email protected]>
drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[]
Hersen Wu <[email protected]>
drm/amd/display: Add array index check for hdcp ddc access
Hersen Wu <[email protected]>
drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6
Alex Hung <[email protected]>
drm/amd/display: Check gpio_id before used as array index
Zhigang Luo <[email protected]>
drm/amdgpu: avoid reading vf2pf info size from FB
Tim Huang <[email protected]>
drm/amd/pm: fix uninitialized variable warnings for vega10_hwmgr
Tim Huang <[email protected]>
drm/amdgpu: fix uninitialized scalar variable warning
Jesse Zhang <[email protected]>
drm/amd/pm: fix the Out-of-bounds read warning
Jesse Zhang <[email protected]>
drm/amd/pm: fix warning using uninitialized value of max_vid_step
Tim Huang <[email protected]>
drm/amd/pm: fix uninitialized variable warning for smu8_hwmgr
Tim Huang <[email protected]>
drm/amdgpu: fix overflowed array index read warning
Ma Jun <[email protected]>
drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr
ZHANG Yuntian <[email protected]>
net: usb: qmi_wwan: add MeiG Smart SRM825L
Rik van Riel <[email protected]>
dma-debug: avoid deadlock between dma debug vs printk and netconsole
Richard Fitzgerald <[email protected]>
i2c: Fix conditional for substituting empty ACPI functions
Takashi Iwai <[email protected]>
ALSA: hda/conexant: Mute speakers at suspend / shutdown
Takashi Iwai <[email protected]>
ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown
Philip Mueller <[email protected]>
drm: panel-orientation-quirks: Add quirk for OrangePi Neo
-------------
Diffstat:
Documentation/locking/hwspinlock.rst | 11 ++ Makefile | 4 +- arch/arm64/include/asm/acpi.h | 12 ++ arch/arm64/kernel/acpi_numa.c | 11 -- arch/mips/kernel/cevt-r4k.c | 15 +- arch/s390/kernel/vmlinux.lds.S | 9 + arch/um/drivers/line.c | 2 + arch/x86/mm/pti.c | 45 +++-- block/bio-integrity.c | 11 +- block/blk-integrity.c | 2 - drivers/acpi/acpi_processor.c | 15 +- drivers/android/binder.c | 1 + drivers/ata/libata-core.c | 4 +- drivers/ata/pata_macio.c | 7 +- drivers/base/devres.c | 1 + drivers/clk/qcom/clk-alpha-pll.c | 6 +- drivers/clocksource/timer-imx-tpm.c | 16 +- drivers/clocksource/timer-of.c | 17 +- drivers/clocksource/timer-of.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 4 +- drivers/gpu/drm/amd/amdgpu/df_v1_7.c | 2 + drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.h | 2 - drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 5 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +- .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 3 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c | 3 + drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 17 +- drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 17 +- .../gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c | 28 ++- drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c | 13 +- .../gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 5 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 15 +- .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 90 +++++++-- .../gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 8 +- .../drm/amd/pm/powerplay/smumgr/vega10_smumgr.c | 6 +- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 + drivers/gpu/drm/i915/i915_sw_fence.c | 8 +- drivers/gpu/drm/meson/meson_plane.c | 17 +- drivers/hid/hid-cougar.c | 2 +- drivers/hv/vmbus_drv.c | 1 + drivers/hwmon/adc128d818.c | 4 +- drivers/hwmon/lm95234.c | 9 +- drivers/hwmon/nct6775.c | 2 +- drivers/hwmon/w83627ehf.c | 4 +- drivers/hwspinlock/hwspinlock_core.c | 28 +++ drivers/hwspinlock/hwspinlock_internal.h | 3 + drivers/iio/adc/ad7124.c | 1 + drivers/iio/adc/ad7606.c | 28 +-- drivers/iio/adc/ad7606.h | 2 + drivers/iio/adc/ad7606_par.c | 46 ++++- drivers/iio/buffer/industrialio-buffer-dmaengine.c | 4 +- drivers/iio/inkern.c | 8 +- drivers/input/misc/uinput.c | 14 ++ drivers/iommu/intel/dmar.c | 2 +- drivers/iommu/sun50i-iommu.c | 1 + drivers/irqchip/irq-armada-370-xp.c | 4 + drivers/irqchip/irq-gic-v2m.c | 6 +- drivers/leds/leds-spi-byte.c | 6 +- drivers/md/dm-init.c | 4 +- drivers/media/platform/qcom/camss/camss.c | 5 +- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 17 +- drivers/media/test-drivers/vivid/vivid-vid-out.c | 16 +- drivers/media/usb/uvc/uvc_driver.c | 18 +- drivers/misc/vmw_vmci/vmci_resource.c | 3 +- drivers/mmc/host/cqhci.c | 2 +- drivers/mmc/host/dw_mmc.c | 4 +- drivers/mmc/host/sdhci-of-aspeed.c | 1 + drivers/net/bareudp.c | 22 +-- drivers/net/can/spi/mcp251x.c | 2 +- drivers/net/dsa/vitesse-vsc73xx-core.c | 10 +- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 20 +- drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 10 +- drivers/net/ethernet/intel/igb/igb_main.c | 10 + drivers/net/ethernet/intel/igc/igc_main.c | 1 + drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- drivers/net/geneve.c | 8 +- drivers/net/usb/ch9200.c | 4 +- drivers/net/usb/cx82310_eth.c | 5 +- drivers/net/usb/ipheth.c | 4 +- drivers/net/usb/kaweth.c | 3 +- drivers/net/usb/mcs7830.c | 4 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/net/usb/sierra_net.c | 6 +- drivers/net/usb/sr9700.c | 4 +- drivers/net/usb/sr9800.c | 5 +- drivers/net/usb/usbnet.c | 23 +-- drivers/net/virtio_net.c | 8 +- .../broadcom/brcm80211/brcmsmac/mac80211_if.c | 1 + drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 3 +- drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 - drivers/net/wireless/marvell/mwifiex/main.h | 3 + drivers/nvme/target/tcp.c | 4 +- drivers/nvmem/core.c | 6 +- drivers/of/irq.c | 15 +- drivers/pci/controller/dwc/pci-keystone.c | 44 ++++- drivers/pci/controller/dwc/pcie-al.c | 16 +- drivers/pci/hotplug/pnv_php.c | 3 +- drivers/pci/pci.c | 35 ++-- drivers/pcmcia/yenta_socket.c | 6 +- drivers/platform/x86/dell-smbios-base.c | 5 +- drivers/staging/iio/frequency/ad9834.c | 2 +- drivers/uio/uio_hv_generic.c | 11 +- drivers/usb/storage/uas.c | 1 + drivers/usb/typec/ucsi/ucsi.h | 2 +- drivers/usb/usbip/stub_rx.c | 77 +++++--- fs/btrfs/extent-tree.c | 32 +++- fs/btrfs/inode.c | 2 +- fs/btrfs/ioctl.c | 5 +- fs/btrfs/transaction.c | 24 +++ fs/btrfs/transaction.h | 2 + fs/ext4/page-io.c | 14 +- fs/fuse/file.c | 8 +- fs/fuse/xattr.c | 4 +- fs/lockd/svc.c | 3 - fs/nfs/callback.c | 3 - fs/nfs/super.c | 2 + fs/nfsd/export.c | 32 +++- fs/nfsd/export.h | 4 +- fs/nfsd/netns.h | 25 ++- fs/nfsd/nfs4proc.c | 6 +- fs/nfsd/nfscache.c | 202 ++++++++++++--------- fs/nfsd/nfsctl.c | 24 ++- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfsfh.c | 3 +- fs/nfsd/nfssvc.c | 38 ++-- fs/nfsd/stats.c | 52 +++--- fs/nfsd/stats.h | 83 ++++----- fs/nfsd/trace.h | 22 +++ fs/nfsd/vfs.c | 6 +- fs/nilfs2/recovery.c | 35 +++- fs/nilfs2/segment.c | 10 +- fs/nilfs2/sysfs.c | 117 +++++++----- fs/notify/fsnotify.c | 31 +++- fs/notify/fsnotify.h | 2 +- fs/notify/mark.c | 32 +++- fs/squashfs/inode.c | 7 +- fs/udf/super.c | 24 ++- include/linux/cgroup-defs.h | 107 +++-------- include/linux/cgroup.h | 22 +-- include/linux/fsnotify_backend.h | 8 +- include/linux/hwspinlock.h | 6 + include/linux/i2c.h | 2 +- include/linux/sunrpc/svc.h | 5 +- include/net/bluetooth/hci_core.h | 5 - kernel/cgroup/cgroup.c | 65 +++---- kernel/dma/debug.c | 5 +- kernel/events/core.c | 18 +- kernel/events/internal.h | 1 + kernel/events/ring_buffer.c | 2 + kernel/events/uprobes.c | 3 +- kernel/locking/rtmutex.c | 4 +- kernel/rcu/tasks.h | 2 +- kernel/smp.c | 1 + kernel/trace/trace.c | 2 + lib/generic-radix-tree.c | 2 + mm/memcontrol.c | 23 ++- net/8021q/vlan_core.c | 7 +- net/bluetooth/mgmt.c | 60 +++--- net/bluetooth/smp.c | 7 - net/bridge/br_fdb.c | 6 +- net/can/bcm.c | 4 + net/core/netclassid_cgroup.c | 7 +- net/core/netprio_cgroup.c | 10 +- net/ethernet/eth.c | 7 +- net/ipv4/af_inet.c | 19 +- net/ipv4/fou.c | 62 ++++--- net/ipv4/gre_offload.c | 12 +- net/ipv4/inet_hashtables.c | 2 +- net/ipv4/tcp_bpf.c | 2 +- net/ipv4/udp_offload.c | 6 +- net/ipv6/ila/ila.h | 1 + net/ipv6/ila/ila_main.c | 6 + net/ipv6/ila/ila_xlat.c | 13 +- net/ipv6/ip6_offload.c | 14 +- net/ipv6/udp_offload.c | 2 - net/mptcp/options.c | 34 ++-- net/mptcp/pm.c | 24 +-- net/mptcp/pm_netlink.c | 59 +++--- net/mptcp/protocol.c | 54 +++--- net/mptcp/protocol.h | 4 +- net/mptcp/subflow.c | 50 ++--- net/netfilter/nf_conncount.c | 8 +- net/sched/sch_cake.c | 11 +- net/sched/sch_netem.c | 9 +- net/sunrpc/stats.c | 2 +- net/sunrpc/svc.c | 36 ++-- net/sunrpc/xprtrdma/svc_rdma_rw.c | 2 + net/sunrpc/xprtsock.c | 7 + net/unix/af_unix.c | 9 +- net/wireless/scan.c | 46 +++-- security/apparmor/apparmorfs.c | 4 + security/smack/smack_lsm.c | 14 +- sound/hda/hdmi_chmap.c | 18 ++ sound/pci/hda/hda_generic.c | 63 +++++++ sound/pci/hda/hda_generic.h | 1 + sound/pci/hda/patch_conexant.c | 13 ++ sound/pci/hda/patch_realtek.c | 10 + sound/soc/soc-dapm.c | 1 + sound/soc/soc-topology.c | 2 + tools/lib/bpf/libbpf.c | 4 +- tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 4 +- 209 files changed, 1848 insertions(+), 1126 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/186 drm: panel-orientation-quirks: Add quirk for OrangePi Neo
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Mueller <[email protected]>
[ Upstream commit d60c429610a14560085d98fa6f4cdb43040ca8f0 ]
This adds a DMI orientation quirk for the OrangePi Neo Linux Gaming Handheld.
--- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/drm_panel_orientation_quirks.c +6 -0
@@ -318,6 +318,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), }, .driver_data = (void *)&lcd1600x2560_leftside_up, + }, { /* OrangePi Neo */ + .matches = { +DMI_EXACT_MATCH (DMI_SYS_VENDOR ,"OrangePi" ), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "NEO-01"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, }, { /* Samsung GalaxyBook 10.6 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 2/186 ALSA: hda/generic: Add a helper to mute speakers at suspend/shutdown
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 6cd23b26b348fa52c88e1adf9c0e48d68e13f95e ]
Some devices indicate click noises at suspend or shutdown when the speakers are unmuted. This patch adds a helper, snd_hda_gen_shutup_speakers(), to work around it. The new function is supposed to be called at suspend or shutdown by the codec driver, and it mutes the speakers.
The mute status isn't cached, hence the original mute state will be restored at resume again.
--- sound/pci/hda/hda_generic.c | 63 +++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_generic.h | 1 + 2 files changed, 64 insertions(+)
sound/pci/hda/hda_generic.c +63 -0
@@ -5067,6 +5067,69 @@ void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on) }EXPORT_SYMBOL_GPL (snd_hda_gen_stream_pm); +/* forcibly mute the speaker output without caching; return true if updated */ +static bool force_mute_output_path (struct hda_codec *codec,hda_nid_t nid) +{ +if (!nid) +return false; +if (!nid_has_mute (codec, nid,HDA_OUTPUT )) +return false;/* no mute, skip */ +if (snd_hda_codec_amp_read (codec, nid,0 ,HDA_OUTPUT ,0 ) & +snd_hda_codec_amp_read (codec, nid,1 ,HDA_OUTPUT ,0 ) & +HDA_AMP_MUTE ) +return false;/* both channels already muted, skip */ + +/* direct amp update without caching */ +snd_hda_codec_write (codec, nid,0 ,AC_VERB_SET_AMP_GAIN_MUTE , +AC_AMP_SET_OUTPUT |AC_AMP_SET_LEFT | +AC_AMP_SET_RIGHT |HDA_AMP_MUTE ); +return true; +} + +/** +* snd_hda_gen_shutup_speakers - Forcibly mute the speaker outputs +* @codec: the HDA codec +* +* Forcibly mute the speaker outputs, to be called at suspend or shutdown. +* +* The mute state done by this function isn't cached, hence the original state +* will be restored at resume. +* +* Return true if the mute state has been changed. +*/ +bool snd_hda_gen_shutup_speakers (struct hda_codec *codec) +{ +struct hda_gen_spec *spec = codec->spec; +const int *paths; +const struct nid_path *path; +int i, p, num_paths; +bool updated = false; + +/* if already powered off, do nothing */ +if (!snd_hdac_is_power_on (&codec->core)) +return false; + +if (spec->autocfg.line_out_type ==AUTO_PIN_SPEAKER_OUT ) { + paths = spec->out_paths; + num_paths = spec->autocfg.line_outs; + }else { + paths = spec->speaker_paths; + num_paths = spec->autocfg.speaker_outs; + } + +for (i =0 ; i < num_paths; i++) { + path =snd_hda_get_path_from_idx (codec, paths[i]); +if (!path) +continue ; +for (p =0 ; p < path->depth; p++) +if (force_mute_output_path (codec, path->path[p])) + updated = true; + } + +return updated; +} +EXPORT_SYMBOL_GPL (snd_hda_gen_shutup_speakers); +/** * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and * set up the hda_gen_spec
sound/pci/hda/hda_generic.h +1 -0
@@ -364,5 +364,6 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,int snd_hda_gen_add_micmute_led_cdev (struct hda_codec *codec,int (*callback)(struct led_classdev *,enum led_brightness )); +bool snd_hda_gen_shutup_speakers (struct hda_codec *codec);#endif /* __SOUND_HDA_GENERIC_H */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 3/186 ALSA: hda/conexant: Mute speakers at suspend / shutdown
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 4f61c8fe35202702426cfc0003e15116a01ba885 ]
Use the new helper to mute speakers at suspend / shutdown for avoiding click noises.
--- sound/pci/hda/patch_conexant.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_conexant.c +2 -0
@@ -181,6 +181,8 @@ static void cx_auto_reboot_notify(struct hda_codec *codec) {struct conexant_spec *spec = codec->spec; +snd_hda_gen_shutup_speakers (codec); +/* Turn the problematic codec into D3 to avoid spurious noises from the internal speaker during (and after) reboot */ cx_auto_turn_eapd (codec, spec->num_eapds, spec->eapds, false);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 4/186 i2c: Fix conditional for substituting empty ACPI functions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit f17c06c6608ad4ecd2ccf321753fb511812d821b ]
Add IS_ENABLED(CONFIG_I2C) to the conditional around a bunch of ACPI functions.
The conditional around these functions depended only on CONFIG_ACPI. But the functions are implemented in I2C core, so are only present if CONFIG_I2C is enabled.
--- include/linux/i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/i2c.h +1 -1
@@ -991,7 +991,7 @@ static inline int of_i2c_get_board_info(struct device *dev,struct acpi_resource ;struct acpi_resource_i2c_serialbus ; -#if IS_ENABLED (CONFIG_ACPI ) +#if IS_ENABLED (CONFIG_ACPI ) &&IS_ENABLED (CONFIG_I2C )bool i2c_acpi_get_i2c_resource (struct acpi_resource *ares,struct acpi_resource_i2c_serialbus **i2c);u32 i2c_acpi_find_bus_speed (struct device *dev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 5/186 dma-debug: avoid deadlock between dma debug vs printk and netconsole
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rik van Riel <[email protected]>
[ Upstream commit bd44ca3de49cc1badcff7a96010fa2c64f04868c ]
Currently the dma debugging code can end up indirectly calling printk under the radix_lock. This happens when a radix tree node allocation fails.
This is a problem because the printk code, when used together with netconsole, can end up inside the dma debugging code while trying to transmit a message over netcons.
This creates the possibility of either a circular deadlock on the same CPU, with that CPU trying to grab the radix_lock twice, or an ABBA deadlock between different CPUs, where one CPU grabs the console lock first and then waits for the radix_lock, while the other CPU is holding the radix_lock and is waiting for the console lock.
The trace captured by lockdep is of the ABBA variant.
-> #2 (&dma_entry_hash[i].lock){-.-.}-{2:2}:
_raw_spin_lock_irqsave+0x5a/0x90
debug_dma_map_page+0x79/0x180
dma_map_page_attrs+0x1d2/0x2f0
bnxt_start_xmit+0x8c6/0x1540
netpoll_start_xmit+0x13f/0x180
netpoll_send_skb+0x20d/0x320
netpoll_send_udp+0x453/0x4a0
write_ext_msg+0x1b9/0x460
console_flush_all+0x2ff/0x5a0
console_unlock+0x55/0x180
vprintk_emit+0x2e3/0x3c0
devkmsg_emit+0x5a/0x80
devkmsg_write+0xfd/0x180
do_iter_readv_writev+0x164/0x1b0
vfs_writev+0xf9/0x2b0
do_writev+0x6d/0x110
do_syscall_64+0x80/0x150
entry_SYSCALL_64_after_hwframe+0x4b/0x53-> #0 (console_owner){-.-.}-{0:0}:
__lock_acquire+0x15d1/0x31a0
lock_acquire+0xe8/0x290
console_flush_all+0x2ea/0x5a0
console_unlock+0x55/0x180
vprintk_emit+0x2e3/0x3c0
_printk+0x59/0x80
warn_alloc+0x122/0x1b0
__alloc_pages_slowpath+0x1101/0x1120
__alloc_pages+0x1eb/0x2c0
alloc_slab_page+0x5f/0x150
new_slab+0x2dc/0x4e0
___slab_alloc+0xdcb/0x1390
kmem_cache_alloc+0x23d/0x360
radix_tree_node_alloc+0x3c/0xf0
radix_tree_insert+0xf5/0x230
add_dma_entry+0xe9/0x360
dma_map_page_attrs+0x1d2/0x2f0
__bnxt_alloc_rx_frag+0x147/0x180
bnxt_alloc_rx_data+0x79/0x160
bnxt_rx_skb+0x29/0xc0
bnxt_rx_pkt+0xe22/0x1570
__bnxt_poll_work+0x101/0x390
bnxt_poll+0x7e/0x320
__napi_poll+0x29/0x160
net_rx_action+0x1e0/0x3e0
handle_softirqs+0x190/0x510
run_ksoftirqd+0x4e/0x90
smpboot_thread_fn+0x1a8/0x270
kthread+0x102/0x120
ret_from_fork+0x2f/0x40
ret_from_fork_asm+0x11/0x20This bug is more likely than it seems, because when one CPU has run out of memory, chances are the other has too.
The good news is, this bug is hidden behind the CONFIG_DMA_API_DEBUG, so not many users are likely to trigger it.
--- kernel/dma/debug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/dma/debug.c +4 -1
@@ -447,8 +447,11 @@ void debug_dma_dump_mappings(struct device *dev)* dma_active_cacheline entry to track per event. dma_map_sg(), on the * other hand, consumes a single dma_debug_entry, but inserts 'nents' * entries into the tree. +* +* Use __GFP_NOWARN because the printk from an OOM, to netconsole, could end +* up right back in the DMA debugging code, leading to a deadlock. */ -static RADIX_TREE(dma_active_cacheline, GFP_ATOMIC); +static RADIX_TREE(dma_active_cacheline, GFP_ATOMIC | __GFP_NOWARN);static DEFINE_SPINLOCK (radix_lock);#define ACTIVE_CACHELINE_MAX_OVERLAP ((1 << RADIX_TREE_MAX_TAGS) - 1)#define CACHELINE_PER_PAGE_SHIFT (PAGE_SHIFT - L1_CACHE_SHIFT)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 6/186 net: usb: qmi_wwan: add MeiG Smart SRM825L
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZHANG Yuntian <[email protected]>
[ Upstream commit 1ca645a2f74a4290527ae27130c8611391b07dbf ]
Add support for MeiG Smart SRM825L which is based on Qualcomm 315 chip.
T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=2dee ProdID=4d22 Rev= 4.14 S: Manufacturer=MEIG S: Product=LTE-A Module S: SerialNumber=6f345e48 C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=896mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) E: Ad=05(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=88(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=50 Driver=qmi_wwan E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms
--- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/usb/qmi_wwan.c +1 -0
@@ -1365,6 +1365,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ + {QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L *//* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 7/186 drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit c0d6bd3cd209419cc46ac49562bef1db65d90e70 ]
Assign value to clock to fix the warning below:
"Using uninitialized value res. Field res.clock is uninitialized"
--- drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c +1 -0
@@ -100,6 +100,7 @@ struct amdgpu_afmt_acr amdgpu_afmt_acr(uint32_t clock)amdgpu_afmt_calc_cts (clock, &res.cts_32khz, &res.n_32khz,32000 );amdgpu_afmt_calc_cts (clock, &res.cts_44_1khz, &res.n_44_1khz,44100 );amdgpu_afmt_calc_cts (clock, &res.cts_48khz, &res.n_48khz,48000 ); + res.clock = clock;return res; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 8/186 drm/amdgpu: fix overflowed array index read warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit ebbc2ada5c636a6a63d8316a3408753768f5aa9f ]
Clear overflowed array index read warning by cast operation.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +2 -1
@@ -368,8 +368,9 @@ static ssize_t amdgpu_debugfs_ring_read(struct file *f, char __user *buf, size_t size, loff_t *pos) { struct amdgpu_ring *ring = file_inode(f)->i_private; -int r, i;uint32_t value, result, early[3 ]; +loff_t i; +int r;if (*pos &3 || size &3 )return -EINVAL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 9/186 drm/amd/pm: fix uninitialized variable warning for smu8_hwmgr
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 86df36b934640866eb249a4488abb148b985a0d9 ]
Clear warnings that using uninitialized value level when fails to get the value from SMU.
--- .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +12 -3
@@ -584,6 +584,7 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr) hwmgr->dyn_state.uvd_clock_voltage_dependency_table;unsigned long clock =0 ;uint32_t level; +int ret;if (NULL == table || table->count <=0 )return -EINVAL ;
@@ -591,7 +592,9 @@ static int smu8_init_uvd_limit(struct pp_hwmgr *hwmgr) data->uvd_dpm.soft_min_clk =0 ; data->uvd_dpm.hard_min_clk =0 ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxUvdLevel, &level); +if (ret) +return ret;if (level < table->count) clock = table->entries[level].vclk;
@@ -611,6 +614,7 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr) hwmgr->dyn_state.vce_clock_voltage_dependency_table;unsigned long clock =0 ;uint32_t level; +int ret;if (NULL == table || table->count <=0 )return -EINVAL ;
@@ -618,7 +622,9 @@ static int smu8_init_vce_limit(struct pp_hwmgr *hwmgr) data->vce_dpm.soft_min_clk =0 ; data->vce_dpm.hard_min_clk =0 ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxEclkLevel, &level); +if (ret) +return ret;if (level < table->count) clock = table->entries[level].ecclk;
@@ -638,6 +644,7 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr) hwmgr->dyn_state.acp_clock_voltage_dependency_table;unsigned long clock =0 ;uint32_t level; +int ret;if (NULL == table || table->count <=0 )return -EINVAL ;
@@ -645,7 +652,9 @@ static int smu8_init_acp_limit(struct pp_hwmgr *hwmgr) data->acp_dpm.soft_min_clk =0 ; data->acp_dpm.hard_min_clk =0 ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetMaxAclkLevel, &level); +if (ret) +return ret;if (level < table->count) clock = table->entries[level].acpclk;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 10/186 drm/amd/pm: fix warning using uninitialized value of max_vid_step
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <[email protected]>
[ Upstream commit 17e3bea65cdc453695b2fe4ff26d25d17f5339e9 ]
Check the return of pp_atomfwctrl_get_Voltage_table_v4 as it may fail to initialize max_vid_step
V2: change the check condition (Tim Huang)
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +4 -1
@@ -2572,8 +2572,11 @@ static int vega10_init_smc_table(struct pp_hwmgr *hwmgr) } } -pp_atomfwctrl_get_voltage_table_v4 (hwmgr,VOLTAGE_TYPE_VDDC , + result =pp_atomfwctrl_get_voltage_table_v4 (hwmgr,VOLTAGE_TYPE_VDDC ,VOLTAGE_OBJ_SVID2 , &voltage_table); +PP_ASSERT_WITH_CODE (!result, +"Failed to get voltage table!" , + return result); pp_table->MaxVidStep = voltage_table.max_vid_step; pp_table->GfxDpmVoltageMode =
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 11/186 drm/amd/pm: fix the Out-of-bounds read warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <[email protected]>
[ Upstream commit 12c6967428a099bbba9dfd247bb4322a984fcc0b ]
using index i - 1U may beyond element index for mc_data[] when i = 0.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c +3 -2
@@ -73,8 +73,9 @@ static int atomctrl_retrieve_ac_timing( j++; }else if ((table->mc_reg_address[i].uc_pre_reg_data &LOW_NIBBLE_MASK ) ==DATA_EQU_PREV ) { - table->mc_reg_table_entry[num_ranges].mc_data[i] = - table->mc_reg_table_entry[num_ranges].mc_data[i-1 ]; +if (i) + table->mc_reg_table_entry[num_ranges].mc_data[i] = + table->mc_reg_table_entry[num_ranges].mc_data[i-1 ]; } } num_ranges++;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 12/186 drm/amdgpu: fix uninitialized scalar variable warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 9a5f15d2a29d06ce5bd50919da7221cda92afb69 ]
Clear warning that uses uninitialized value fw_size.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +2 -0
@@ -404,6 +404,8 @@ static void amdgpu_virt_add_bad_page(struct amdgpu_device *adev,uint64_t retired_page;uint32_t bp_idx, bp_cnt; +memset (&bp,0 ,sizeof (bp)); +if (bp_block_size) { bp_cnt = bp_block_size /sizeof (uint64_t );for (bp_idx =0 ; bp_idx < bp_cnt; bp_idx++) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 13/186 drm/amd/pm: fix uninitialized variable warnings for vega10_hwmgr
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 5fa7d540d95d97ddc021a74583f6b3da4df9c93a ]
Clear warnings that using uninitialized variable when fails to get the valid value from SMU.
--- .../drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 46 ++++++++++++++----- .../amd/pm/powerplay/smumgr/vega10_smumgr.c | 6 ++- 2 files changed, 39 insertions(+), 13 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +34 -12
@@ -355,13 +355,13 @@ static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr)return 0 ; } -static void vega10_init_dpm_defaults (struct pp_hwmgr *hwmgr) +static int vega10_init_dpm_defaults (struct pp_hwmgr *hwmgr) {struct vega10_hwmgr *data = hwmgr->backend; -int i;uint32_t sub_vendor_id, hw_revision;uint32_t top32, bottom32;struct amdgpu_device *adev = hwmgr->adev; +int ret, i;vega10_initialize_power_tune_defaults (hwmgr);
@@ -486,9 +486,12 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)if (data->registry_data.vr0hot_enabled) data->smu_features[GNLD_VR0HOT ].supported = true; -smum_send_msg_to_smc (hwmgr, + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetSmuVersion, &hwmgr->smu_version); +if (ret) +return ret; +/* ACG firmware has major version 5 */ if ((hwmgr->smu_version &0xff000000 ) ==0x5000000 ) data->smu_features[GNLD_ACG ].supported = true;
@@ -506,10 +509,16 @@ static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr) data->smu_features[GNLD_PCC_LIMIT ].supported = true;/* Get the SN to turn into a Unique ID */ -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32); +if (ret) +return ret; + + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32); +if (ret) +return ret; adev->unique_id = ((uint64_t )bottom32 <<32 ) | top32; +return 0 ; }#ifdef PPLIB_VEGA10_EVV_SUPPORT
@@ -883,7 +892,9 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)vega10_set_features_platform_caps (hwmgr); -vega10_init_dpm_defaults (hwmgr); + result =vega10_init_dpm_defaults (hwmgr); +if (result) +return result;#ifdef PPLIB_VEGA10_EVV_SUPPORT /* Get leakage voltage based on leakage ID. */
@@ -3879,11 +3890,14 @@ static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query) {uint32_t value; +int ret;if (!query)return -EINVAL ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrPkgPwr, &value); +if (ret) +return ret;/* SMC returning actual watts, keep consistent with legacy asics, low 8 bit as 8 fractional bits */ *query = value <<8 ;
@@ -4636,14 +4650,16 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;PPTable_t *pptable = &(data->smc_state_table.pp_table); -int i, now, size =0 , count =0 ; +int i, ret, now, size =0 , count =0 ;switch (type) {case PP_SCLK :if (data->registry_data.sclk_dpm_key_disabled)break ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex, &now); +if (ret) +break ;if (hwmgr->pp_one_vf && (hwmgr->dpm_level ==AMD_DPM_FORCED_LEVEL_PROFILE_PEAK ))
@@ -4659,7 +4675,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,if (data->registry_data.mclk_dpm_key_disabled)break ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentUclkIndex, &now); +if (ret) +break ;for (i =0 ; i < mclk_table->count; i++) size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4670,7 +4688,9 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,if (data->registry_data.socclk_dpm_key_disabled)break ; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetCurrentSocclkIndex, &now); +if (ret) +break ;for (i =0 ; i < soc_table->count; i++) size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4681,8 +4701,10 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,if (data->registry_data.dcefclk_dpm_key_disabled)break ; -smum_send_msg_to_smc_with_parameter (hwmgr, + ret =smum_send_msg_to_smc_with_parameter (hwmgr, PPSMC_MSG_GetClockFreqMHz,CLK_DCEFCLK , &now); +if (ret) +break ;for (i =0 ; i < dcef_table->count; i++) size += sprintf(buf + size, "%d: %uMhz %s\n",
drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c +5 -1
@@ -131,13 +131,17 @@ int vega10_get_enabled_smc_features(struct pp_hwmgr *hwmgr, uint64_t *features_enabled) {uint32_t enabled_features; +int ret;if (features_enabled ==NULL )return -EINVAL ; -smum_send_msg_to_smc (hwmgr, + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_GetEnabledSmuFeatures, &enabled_features); +if (ret) +return ret; + *features_enabled = enabled_features;return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 14/186 drm/amdgpu: avoid reading vf2pf info size from FB
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhigang Luo <[email protected]>
[ Upstream commit 3bcc0ee14768d886cedff65da72d83d375a31a56 ]
VF can't access FB when host is doing mode1 reset. Using sizeof to get vf2pf info size, instead of reading it from vf2pf header stored in FB.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +1 -1
@@ -552,7 +552,7 @@ static int amdgpu_virt_write_vf2pf_data(struct amdgpu_device *adev) vf2pf_info->checksum =amd_sriov_msg_checksum ( - vf2pf_info, vf2pf_info->header.size,0 ,0 ); + vf2pf_info,sizeof (*vf2pf_info),0 ,0 );return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 15/186 drm/amd/display: Check gpio_id before used as array index
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 2a5626eeb3b5eec7a36886f9556113dd93ec8ed6 ]
[WHY & HOW]GPIO_ID_UNKNOWN (-1) is not a valid value for array index and therefore should be checked in advance.
This fixes 5 OVERRUN issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +11 -2
@@ -241,6 +241,9 @@ static bool is_pin_busy( enum gpio_id id, uint32_t en) { +if (id ==GPIO_ID_UNKNOWN ) +return false; +return service->busyness[id][en]; }
@@ -249,6 +252,9 @@ static void set_pin_busy( enum gpio_id id, uint32_t en) { +if (id ==GPIO_ID_UNKNOWN ) +return ; + service->busyness[id][en] = true; }
@@ -257,6 +263,9 @@ static void set_pin_free( enum gpio_id id, uint32_t en) { +if (id ==GPIO_ID_UNKNOWN ) +return ; + service->busyness[id][en] = false; }
@@ -265,7 +274,7 @@ enum gpio_result dal_gpio_service_lock( enum gpio_id id, uint32_t en) { -if (!service->busyness[id]) { +if (id !=GPIO_ID_UNKNOWN && !service->busyness[id]) {ASSERT_CRITICAL (false);return GPIO_RESULT_OPEN_FAILED ; }
@@ -279,7 +288,7 @@ enum gpio_result dal_gpio_service_unlock( enum gpio_id id, uint32_t en) { -if (!service->busyness[id]) { +if (id !=GPIO_ID_UNKNOWN && !service->busyness[id]) {ASSERT_CRITICAL (false);return GPIO_RESULT_OPEN_FAILED ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 16/186 drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hersen Wu <[email protected]>
[ Upstream commit 84723eb6068c50610c5c0893980d230d7afa2105 ]
[Why]
Coverity reports OVERRUN warning. Should abort amdgpu_dm initialize.
[How]
Return failure to amdgpu_dm_init.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +4 -1
@@ -3341,7 +3341,10 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)/* There is one primary plane per CRTC */ primary_planes = dm->dc->caps.max_streams; -ASSERT (primary_planes <=AMDGPU_MAX_PLANES ); +if (primary_planes >AMDGPU_MAX_PLANES ) { +DRM_ERROR ("DM: Plane nums out of 6 planes\n" ); +return -EINVAL ; + }/* * Initialize primary planes, implicit planes for legacy IOCTLS.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 17/186 drm/amd/display: Add array index check for hdcp ddc access
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hersen Wu <[email protected]>
[ Upstream commit 4e70c0f5251c25885c31ee84a31f99a01f7cf50e ]
[Why]
Coverity reports OVERRUN warning. Do not check if array index valid.
[How]
Check msg_id valid and valid array index.
--- .../drm/amd/display/modules/hdcp/hdcp_ddc.c | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +24 -4
@@ -156,11 +156,16 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp,uint32_t cur_size =0 ;uint32_t data_offset =0 ; -if (msg_id ==MOD_HDCP_MESSAGE_ID_INVALID ) { +if (msg_id ==MOD_HDCP_MESSAGE_ID_INVALID || + msg_id >=MOD_HDCP_MESSAGE_ID_MAX )return MOD_HDCP_STATUS_DDC_FAILURE ; - }if (is_dp_hdcp (hdcp)) { +int num_dpcd_addrs =sizeof (hdcp_dpcd_addrs) / +sizeof (hdcp_dpcd_addrs[0 ]); +if (msg_id >= num_dpcd_addrs) +return MOD_HDCP_STATUS_DDC_FAILURE ; +while (buf_len >0 ) { cur_size =MIN (buf_len,HDCP_MAX_AUX_TRANSACTION_SIZE ); success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
@@ -175,6 +180,11 @@ static enum mod_hdcp_status read(struct mod_hdcp *hdcp, data_offset += cur_size; } }else { +int num_i2c_offsets =sizeof (hdcp_i2c_offsets) / +sizeof (hdcp_i2c_offsets[0 ]); +if (msg_id >= num_i2c_offsets) +return MOD_HDCP_STATUS_DDC_FAILURE ; + success = hdcp->config.ddc.funcs.read_i2c( hdcp->config.ddc.handle, HDCP_I2C_ADDR,
@@ -219,11 +229,16 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp,uint32_t cur_size =0 ;uint32_t data_offset =0 ; -if (msg_id ==MOD_HDCP_MESSAGE_ID_INVALID ) { +if (msg_id ==MOD_HDCP_MESSAGE_ID_INVALID || + msg_id >=MOD_HDCP_MESSAGE_ID_MAX )return MOD_HDCP_STATUS_DDC_FAILURE ; - }if (is_dp_hdcp (hdcp)) { +int num_dpcd_addrs =sizeof (hdcp_dpcd_addrs) / +sizeof (hdcp_dpcd_addrs[0 ]); +if (msg_id >= num_dpcd_addrs) +return MOD_HDCP_STATUS_DDC_FAILURE ; +while (buf_len >0 ) { cur_size =MIN (buf_len,HDCP_MAX_AUX_TRANSACTION_SIZE ); success = hdcp->config.ddc.funcs.write_dpcd(
@@ -239,6 +254,11 @@ static enum mod_hdcp_status write(struct mod_hdcp *hdcp, data_offset += cur_size; } }else { +int num_i2c_offsets =sizeof (hdcp_i2c_offsets) / +sizeof (hdcp_i2c_offsets[0 ]); +if (msg_id >= num_i2c_offsets) +return MOD_HDCP_STATUS_DDC_FAILURE ; + hdcp->buf[0 ] = hdcp_i2c_offsets[msg_id];memmove (&hdcp->buf[1 ], buf, buf_len); success = hdcp->config.ddc.funcs.write_i2c(
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 18/186 drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[]
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit b38a4815f79b87efb196cd5121579fc51e29a7fb ]
[WHY & HOW]num_valid_sets needs to be checked to avoid a negative index when accessing reader_wm_sets[num_valid_sets - 1].
This fixes an OVERRUN issue reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +2 -1
@@ -455,7 +455,8 @@ static void build_watermark_ranges(struct clk_bw_params *bw_params, struct pp_sm ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz =PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX ;/* Modify previous watermark range to cover up to max */ - ranges->reader_wm_sets[num_valid_sets -1 ].max_fill_clk_mhz =PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX ; +if (num_valid_sets >0 ) + ranges->reader_wm_sets[num_valid_sets -1 ].max_fill_clk_mhz =PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX ; } num_valid_sets++; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 19/186 drm/amd/display: Check msg_id before processing transcation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit fa71face755e27dc44bc296416ebdf2c67163316 ]
[WHY & HOW]HDCP_MESSAGE_ID_INVALID (-1) is not a valid msg_id nor is it a valid array index, and it needs checking before used.
This fixes 4 OVERRUN issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c +15 -2
@@ -130,13 +130,21 @@ static bool hdmi_14_process_transaction(const uint8_t hdcp_i2c_addr_link_primary =0x3a ;/* 0x74 >> 1*/ const uint8_t hdcp_i2c_addr_link_secondary =0x3b ;/* 0x76 >> 1*/ struct i2c_command i2c_command; -uint8_t offset = hdcp_i2c_offsets[message_info->msg_id]; +uint8_t offset;struct i2c_payload i2c_payloads[] = { - { true,0 ,1 , &offset }, + { true,0 ,1 ,0 },/* actual hdcp payload, will be filled later, zeroed for now*/ {0 } }; +if (message_info->msg_id ==HDCP_MESSAGE_ID_INVALID ) { +DC_LOG_ERROR ("%s: Invalid message_info msg_id - %d\n" , __func__, message_info->msg_id); +return false; + } + + offset = hdcp_i2c_offsets[message_info->msg_id]; + i2c_payloads[0 ].data = &offset; +switch (message_info->link) {case HDCP_LINK_SECONDARY : i2c_payloads[0 ].address = hdcp_i2c_addr_link_secondary;
@@ -310,6 +318,11 @@ static bool dp_11_process_transaction( struct dc_link *link, struct hdcp_protection_message *message_info) { +if (message_info->msg_id ==HDCP_MESSAGE_ID_INVALID ) { +DC_LOG_ERROR ("%s: Invalid message_info msg_id - %d\n" , __func__, message_info->msg_id); +return false; + } + return dpcd_access_helper( link, message_info->length,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 20/186 drm/amd/display: Fix Coverity INTEGER_OVERFLOW within dal_gpio_service_create
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hersen Wu <[email protected]>
[ Upstream commit c6077aa66fa230d12f37fef01161ef080d13b726 ]
[Why]
For subtraction, coverity reports integer overflow warning message when variable type is uint32_t.
[How]
Change variable type to int32_t.
--- drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +2 -2
@@ -58,7 +58,7 @@ struct gpio_service *dal_gpio_service_create( struct dc_context *ctx) {struct gpio_service *service; -uint32_t index_of_id; +int32_t index_of_id; service =kzalloc (sizeof (struct gpio_service ),GFP_KERNEL );
@@ -114,7 +114,7 @@ struct gpio_service *dal_gpio_service_create(return service; failure_2: -while (index_of_id) { +while (index_of_id >0 ) { --index_of_id;kfree (service->busyness[index_of_id]); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 21/186 drm/amdgpu/pm: Fix uninitialized variable agc_btc_response
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit df4409d8a04dd39d7f2aa0c5f528a56b99eaaa13 ]
Assign an default value to agc_btc_response in failed case
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +7 -2
@@ -2361,15 +2361,20 @@ static int vega10_acg_enable(struct pp_hwmgr *hwmgr) {struct vega10_hwmgr *data = hwmgr->backend;uint32_t agc_btc_response; +int ret;if (data->smu_features[GNLD_ACG ].supported) {if (0 ==vega10_enable_smc_features (hwmgr, true, data->smu_features[GNLD_DPM_PREFETCHER ].smu_feature_bitmap)) data->smu_features[GNLD_DPM_PREFETCHER ].enabled = true; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_InitializeAcg,NULL ); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_InitializeAcg,NULL ); +if (ret) +return ret; -smum_send_msg_to_smc (hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response); + ret =smum_send_msg_to_smc (hwmgr, PPSMC_MSG_RunAcgBtc, &agc_btc_response); +if (ret) + agc_btc_response =0 ;if (1 == agc_btc_response) {if (1 == data->acg_loop_state)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 22/186 drm/amdgpu: Fix out-of-bounds write warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit be1684930f5262a622d40ce7a6f1423530d87f89 ]
Check the ring type value to fix the out-of-bounds write warning
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +1 -1
@@ -260,7 +260,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ring->priority =DRM_SCHED_PRIORITY_NORMAL ;mutex_init (&ring->priority_mutex); -if (!ring->no_scheduler) { +if (!ring->no_scheduler && ring->funcs->type <AMDGPU_HW_IP_NUM ) { hw_ip = ring->funcs->type; num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds; adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 23/186 drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit d768394fa99467bcf2703bde74ddc96eeb0b71fa ]
Check the fb_channel_number range to avoid the array out-of-bounds read error
--- drivers/gpu/drm/amd/amdgpu/df_v1_7.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/df_v1_7.c +2 -0
@@ -70,6 +70,8 @@ static u32 df_v1_7_get_hbm_channel_number(struct amdgpu_device *adev)int fb_channel_number; fb_channel_number = adev->df.funcs->get_fb_channel_number (adev); +if (fb_channel_number >=ARRAY_SIZE (df_v1_7_channel_number)) + fb_channel_number =0 ;return df_v1_7_channel_number[fb_channel_number]; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 24/186 drm/amdgpu: fix ucode out-of-bounds read warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 8944acd0f9db33e17f387fdc75d33bb473d7936f ]
Clear warning that read ucode[] may out-of-bounds.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +3 -0
@@ -213,6 +213,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,struct amdgpu_firmware_info *ucode; id =fw_type_convert (cgs_device, type); +if (id >=AMDGPU_UCODE_ID_MAXIMUM ) +return -EINVAL ; + ucode = &adev->firmware.ucode[id];if (ucode->fw ==NULL )return -EINVAL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 25/186 drm/amdgpu: fix mc_data out-of-bounds read warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tim Huang <[email protected]>
[ Upstream commit 51dfc0a4d609fe700750a62f41447f01b8c9ea50 ]
Clear warning that read mc_data[i-1] may out-of-bounds.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +2 -0
@@ -1626,6 +1626,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev, (u32 )le32_to_cpu (*((u32 *)reg_data + j)); j++; }else if ((reg_table->mc_reg_address[i].pre_reg_data &LOW_NIBBLE_MASK ) ==DATA_EQU_PREV ) { +if (i ==0 ) +continue ; reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = reg_table->mc_reg_table_entry[num_ranges].mc_data[i -1 ]; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 26/186 drm/amdkfd: Reconcile the definition and use of oem_id in struct kfd_topology_device
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chen <[email protected]>
[ Upstream commit 10f624ef239bd136cdcc5bbc626157a57b938a31 ]
Currently oem_id is defined as uint8_t[6] and casted to uint64_t* in some use case. This would lead code scanner to complain about access beyond. Re-define it in union to enforce 8-byte size and alignment to avoid potential issue.
--- drivers/gpu/drm/amd/amdkfd/kfd_crat.h | 2 -- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +-- drivers/gpu/drm/amd/amdkfd/kfd_topology.h | 5 ++++- 3 files changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_crat.h +0 -2
@@ -42,8 +42,6 @@#define CRAT_OEMTABLEID_LENGTH 8#define CRAT_RESERVED_LENGTH 6 -#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1) -/* Compute Unit flags */ #define COMPUTE_UNIT_CPU (1 << 0)/* Create Virtual CRAT for CPU */ #define COMPUTE_UNIT_GPU (1 << 1)/* Create Virtual CRAT for GPU */
drivers/gpu/drm/amd/amdkfd/kfd_topology.c +1 -2
@@ -906,8 +906,7 @@ static void kfd_update_system_properties(void) dev =list_last_entry (&topology_device_list, struct kfd_topology_device, list);if (dev) { - sys_props.platform_id = - (*((uint64_t *)dev->oem_id)) &CRAT_OEMID_64BIT_MASK ; + sys_props.platform_id = dev->oem_id64; sys_props.platform_oem = *((uint64_t *)dev->oem_table_id); sys_props.platform_rev = dev->oem_revision; }
drivers/gpu/drm/amd/amdkfd/kfd_topology.h +4 -1
@@ -182,7 +182,10 @@ struct kfd_topology_device {struct attribute attr_gpuid;struct attribute attr_name;struct attribute attr_props; -uint8_t oem_id[CRAT_OEMID_LENGTH ]; +union { +uint8_t oem_id[CRAT_OEMID_LENGTH ]; +uint64_t oem_id64; + };uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH ];uint32_t oem_revision; };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 27/186 apparmor: fix possible NULL pointer dereference
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leesoo Ahn <[email protected]>
[ Upstream commit 3dd384108d53834002be5630132ad5c3f32166ad ]
profile->parent->dents[AAFS_PROF_DIR] could be NULL only if its parent is made from __create_missing_ancestors(..) and 'ent->old' is NULL in aa_replace_profiles(..).
In that case, it must return an error code and the code, -ENOENT represents its state that the path of its parent is not existed yet.
BUG: kernel NULL pointer dereference, address: 0000000000000030 PGD 0 P4D 0 PREEMPT SMP PTI CPU: 4 PID: 3362 Comm: apparmor_parser Not tainted 6.8.0-24-generic #24 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 RIP: 0010:aafs_create.constprop.0+0x7f/0x130 Code: 4c 63 e0 48 83 c4 18 4c 89 e0 5b 41 5c 41 5d 41 5e 41 5f 5d 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 c3 cc cc cc cc <4d> 8b 55 30 4d 8d ba a0 00 00 00 4c 89 55 c0 4c 89 ff e8 7a 6a ae RSP: 0018:ffffc9000b2c7c98 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000000041ed RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc9000b2c7cd8 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82baac10 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007be9f22cf740(0000) GS:ffff88817bc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000030 CR3: 0000000134b08000 CR4: 00000000000006f0 Call Trace: <TASK> ? show_regs+0x6d/0x80 ? __die+0x24/0x80 ? page_fault_oops+0x99/0x1b0 ? kernelmode_fixup_or_oops+0xb2/0x140 ? __bad_area_nosemaphore+0x1a5/0x2c0 ? find_vma+0x34/0x60 ? bad_area_nosemaphore+0x16/0x30 ? do_user_addr_fault+0x2a2/0x6b0 ? exc_page_fault+0x83/0x1b0 ? asm_exc_page_fault+0x27/0x30 ? aafs_create.constprop.0+0x7f/0x130 ? aafs_create.constprop.0+0x51/0x130 __aafs_profile_mkdir+0x3d6/0x480 aa_replace_profiles+0x83f/0x1270 policy_update+0xe3/0x180 profile_load+0xbc/0x150 ? rw_verify_area+0x47/0x140 vfs_write+0x100/0x480 ? __x64_sys_openat+0x55/0xa0 ? syscall_exit_to_user_mode+0x86/0x260 ksys_write+0x73/0x100 __x64_sys_write+0x19/0x30 x64_sys_call+0x7e/0x25c0 do_syscall_64+0x7f/0x180 entry_SYSCALL_64_after_hwframe+0x78/0x80 RIP: 0033:0x7be9f211c574 Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d d5 ea 0e 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 55 48 89 e5 48 83 ec 20 48 89 RSP: 002b:00007ffd26f2b8c8 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00005d504415e200 RCX: 00007be9f211c574 RDX: 0000000000001fc1 RSI: 00005d504418bc80 RDI: 0000000000000004 RBP: 0000000000001fc1 R08: 0000000000001fc1 R09: 0000000080000000 R10: 0000000000000000 R11: 0000000000000202 R12: 00005d504418bc80 R13: 0000000000000004 R14: 00007ffd26f2b9b0 R15: 00007ffd26f2ba30 </TASK> Modules linked in: snd_seq_dummy snd_hrtimer qrtr snd_hda_codec_generic snd_hda_intel snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec snd_hda_core snd_hwdep snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device i2c_i801 snd_timer i2c_smbus qxl snd soundcore drm_ttm_helper lpc_ich ttm joydev input_leds serio_raw mac_hid binfmt_misc msr parport_pc ppdev lp parport efi_pstore nfnetlink dmi_sysfs qemu_fw_cfg ip_tables x_tables autofs4 hid_generic usbhid hid ahci libahci psmouse virtio_rng xhci_pci xhci_pci_renesas CR2: 0000000000000030 ---[ end trace 0000000000000000 ]--- RIP: 0010:aafs_create.constprop.0+0x7f/0x130 Code: 4c 63 e0 48 83 c4 18 4c 89 e0 5b 41 5c 41 5d 41 5e 41 5f 5d 31 d2 31 c9 31 f6 31 ff 45 31 c0 45 31 c9 45 31 d2 c3 cc cc cc cc <4d> 8b 55 30 4d 8d ba a0 00 00 00 4c 89 55 c0 4c 89 ff e8 7a 6a ae RSP: 0018:ffffc9000b2c7c98 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 00000000000041ed RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc9000b2c7cd8 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff82baac10 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007be9f22cf740(0000) GS:ffff88817bc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000030 CR3: 0000000134b08000 CR4: 00000000000006f0
--- security/apparmor/apparmorfs.c | 4 ++++ 1 file changed, 4 insertions(+)
security/apparmor/apparmorfs.c +4 -0
@@ -1679,6 +1679,10 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)struct aa_profile *p; p =aa_deref_parent (profile); dent =prof_dir (p); +if (!dent) { + error = -ENOENT ; + goto fail2; + }/* adding to parent that previously didn't have children */ dent =aafs_create_dir ("profiles" , dent);if (IS_ERR (dent))
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 28/186 drm/amdgpu/pm: Check input value for CUSTOM profile mode setting on legacy SOCs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Jun <[email protected]>
[ Upstream commit df0a9bd92fbbd3fcafcb2bce6463c9228a3e6868 ]
Check the input value for CUSTOM profile mode setting on legacy SOCs. Otherwise we may use uninitalized value of input[]
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 2 +- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +1 -1
@@ -5190,7 +5190,7 @@ static int smu7_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint mode = input[size];switch (mode) {case PP_SMC_POWER_PROFILE_CUSTOM : -if (size <8 && size !=0 ) +if (size !=8 && size !=0 )return -EINVAL ;/* If only CUSTOM is passed in, use the saved values. Check * that we actually have a CUSTOM profile by ensuring that
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +6 -2
@@ -4095,9 +4095,11 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uiif (power_profile_mode ==PP_SMC_POWER_PROFILE_CUSTOM ) {struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); -if (size ==0 && !data->is_custom_profile_set) + +if (size !=10 && size !=0 )return -EINVAL ; -if (size <10 && size !=0 ) + +if (size ==0 && !data->is_custom_profile_set)return -EINVAL ; result = vega20_get_activity_monitor_coeff(hwmgr,
@@ -4159,6 +4161,8 @@ static int vega20_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui activity_monitor.Fclk_PD_Data_error_coeff = input[8 ]; activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9 ];break ; +default : +return -EINVAL ; } result = vega20_set_activity_monitor_coeff(hwmgr,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 29/186 drm/amdgpu: the warning dereferencing obj for nbio_v7_4
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <[email protected]>
[ Upstream commit d190b459b2a4304307c3468ed97477b808381011 ]
if ras_manager obj null, don't print NBIO err data
--- drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c +1 -1
@@ -313,7 +313,7 @@ static void nbio_v7_4_handle_ras_controller_intr_no_bifring(struct amdgpu_device RAS_CNTLR_INTERRUPT_CLEAR, 1);WREG32_SOC15 (NBIO ,0 , mmBIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl); -if (!ras->disable_ras_err_cnt_harvest) { +if (ras && !ras->disable_ras_err_cnt_harvest && obj) {/* * clear error status after ras_controller_intr * according to hw team and count ue number
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 30/186 drm/amd/pm: check negtive return for table entries
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <[email protected]>
[ Upstream commit f76059fe14395b37ba8d997eb0381b1b9e80a939 ]
Function hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr) returns a negative number
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c +8 -5
@@ -30,9 +30,8 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr) {int result;unsigned int i; -unsigned int table_entries;struct pp_power_state *state; -int size; +int size, table_entries;if (hwmgr->hwmgr_func->get_num_of_pp_table_entries ==NULL )return 0 ;
@@ -40,15 +39,19 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)if (hwmgr->hwmgr_func->get_power_state_size ==NULL )return 0 ; - hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries (hwmgr); + table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries (hwmgr); - hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size (hwmgr) + + size = hwmgr->hwmgr_func->get_power_state_size (hwmgr) +sizeof (struct pp_power_state ); -if (table_entries ==0 || size ==0 ) { +if (table_entries <=0 || size ==0 ) {pr_warn ("Please check whether power state management is supported on this asic\n" ); + hwmgr->num_ps =0 ; + hwmgr->ps_size =0 ;return 0 ; } + hwmgr->num_ps = table_entries; + hwmgr->ps_size = size; hwmgr->ps =kcalloc (table_entries, size,GFP_KERNEL );if (hwmgr->ps ==NULL )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 31/186 wifi: iwlwifi: remove fw_running op
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar S Matityahu <[email protected]>
[ Upstream commit 37733bffda3285d18bd1d72c14b3a1cf39c56a5e ]
fw_running assumes that memory can be retrieved only after alive. This assumption is no longer true as we support dump before alive. To avoid invalid access to the NIC, check that STATUS_DEVICE_ENABLED bit in trans status is set before dumping instead of the prior check.
--- drivers/net/wireless/intel/iwlwifi/fw/debugfs.c | 3 +-- drivers/net/wireless/intel/iwlwifi/fw/runtime.h | 1 - drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 ------ 3 files changed, 1 insertion(+), 9 deletions(-)
drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +1 -2
@@ -275,8 +275,7 @@ static ssize_t iwl_dbgfs_send_hcmd_write(struct iwl_fw_runtime *fwrt, char *buf, .data = { NULL, }, }; -if (fwrt->ops && fwrt->ops->fw_running && - !fwrt->ops->fw_running (fwrt->ops_ctx)) +if (!iwl_trans_fw_running (fwrt->trans))return -EIO ;if (count < header_size +1 || count >1024 *4 )
drivers/net/wireless/intel/iwlwifi/fw/runtime.h +0 -1
@@ -72,7 +72,6 @@struct iwl_fw_runtime_ops {int (*dump_start)(void *ctx);void (*dump_end)(void *ctx); -bool (*fw_running)(void *ctx);int (*send_hcmd)(void *ctx,struct iwl_host_cmd *host_cmd);bool (*d3_debug_enable)(void *ctx); };
drivers/net/wireless/intel/iwlwifi/mvm/ops.c +0 -6
@@ -577,11 +577,6 @@ static void iwl_mvm_fwrt_dump_end(void *ctx)mutex_unlock (&mvm->mutex); } -static bool iwl_mvm_fwrt_fw_running (void *ctx) -{ -return iwl_mvm_firmware_running (ctx); -} -static int iwl_mvm_fwrt_send_hcmd (void *ctx,struct iwl_host_cmd *host_cmd) {struct iwl_mvm *mvm = (struct iwl_mvm *)ctx;
@@ -602,7 +597,6 @@ static bool iwl_mvm_d3_debug_enable(void *ctx)static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { .dump_start = iwl_mvm_fwrt_dump_start, .dump_end = iwl_mvm_fwrt_dump_end, - .fw_running = iwl_mvm_fwrt_fw_running, .send_hcmd = iwl_mvm_fwrt_send_hcmd, .d3_debug_enable = iwl_mvm_d3_debug_enable, };
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 32/186 PCI: al: Check IORESOURCE_BUS existence during probe
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <[email protected]>
[ Upstream commit a9927c2cac6e9831361e43a14d91277818154e6a ]
If IORESOURCE_BUS is not provided in Device Tree it will be fabricated in of_pci_parse_bus_range(), so NULL pointer dereference should not happen here.
But that's hard to verify, so check for NULL anyway.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/pci/controller/dwc/pcie-al.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/pci/controller/dwc/pcie-al.c +13 -3
@@ -250,18 +250,24 @@ static struct pci_ops al_child_pci_ops = { .write = pci_generic_config_write, }; -static void al_pcie_config_prepare (struct al_pcie *pcie) +static int al_pcie_config_prepare (struct al_pcie *pcie) {struct al_pcie_target_bus_cfg *target_bus_cfg;struct pcie_port *pp = &pcie->pci->pp;unsigned int ecam_bus_mask; +struct resource_entry *ft;u32 cfg_control_offset; +struct resource *bus;u8 subordinate_bus;u8 secondary_bus;u32 cfg_control;u32 reg; -struct resource *bus =resource_list_first_type (&pp->bridge->windows,IORESOURCE_BUS )->res; + ft =resource_list_first_type (&pp->bridge->windows,IORESOURCE_BUS ); +if (!ft) +return -ENODEV ; + + bus = ft->res; target_bus_cfg = &pcie->target_bus_cfg; ecam_bus_mask = (pcie->ecam_size >>20 ) -1 ;
@@ -295,6 +301,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)FIELD_PREP (CFG_CONTROL_SEC_BUS_MASK , secondary_bus);al_pcie_controller_writel (pcie, cfg_control_offset, reg); + +return 0 ; }static int al_pcie_host_init (struct pcie_port *pp)
@@ -313,7 +321,9 @@ static int al_pcie_host_init(struct pcie_port *pp)if (rc)return rc; -al_pcie_config_prepare (pcie); + rc =al_pcie_config_prepare (pcie); +if (rc) +return rc;return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 33/186 hwspinlock: Introduce hwspin_lock_bust()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Maina <[email protected]>
[ Upstream commit 7c327d56597d8de1680cf24e956b704270d3d84a ]
When a remoteproc crashes or goes down unexpectedly this can result in a state where locks held by the remoteproc will remain locked possibly resulting in deadlock. This new API hwspin_lock_bust() allows hwspinlock implementers to define a bust operation for freeing previously acquired hwspinlocks after verifying ownership of the acquired lock.
--- Documentation/locking/hwspinlock.rst | 11 ++++++++++ drivers/hwspinlock/hwspinlock_core.c | 28 ++++++++++++++++++++++++ drivers/hwspinlock/hwspinlock_internal.h | 3 +++ include/linux/hwspinlock.h | 6 +++++ 4 files changed, 48 insertions(+)
Documentation/locking/hwspinlock.rst +11 -0
@@ -85,6 +85,17 @@ is already free). Should be called from a process context (might sleep). +:: + + int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id); + +After verifying the owner of the hwspinlock, release a previously acquired +hwspinlock; returns 0 on success, or an appropriate error code on failure +(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific +hwspinlock). + +Should be called from a process context (might sleep). + :: int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
drivers/hwspinlock/hwspinlock_core.c +28 -0
@@ -302,6 +302,34 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) }EXPORT_SYMBOL_GPL (__hwspin_unlock); +/** +* hwspin_lock_bust() - bust a specific hwspinlock +* @hwlock: a previously-acquired hwspinlock which we want to bust +* @id: identifier of the remote lock holder, if applicable +* +* This function will bust a hwspinlock that was previously acquired as +* long as the current owner of the lock matches the id given by the caller. +* +* Context: Process context. +* +* Returns: 0 on success, or -EINVAL if the hwspinlock does not exist, or +* the bust operation fails, and -EOPNOTSUPP if the bust operation is not +* defined for the hwspinlock. +*/ +int hwspin_lock_bust (struct hwspinlock *hwlock,unsigned int id) +{ +if (WARN_ON (!hwlock)) +return -EINVAL ; + +if (!hwlock->bank->ops->bust) { +pr_err ("bust operation not defined\n" ); +return -EOPNOTSUPP ; + } + +return hwlock->bank->ops->bust (hwlock, id); +} +EXPORT_SYMBOL_GPL (hwspin_lock_bust); +/** * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id * @bank: the hwspinlock device bank
drivers/hwspinlock/hwspinlock_internal.h +3 -0
@@ -21,6 +21,8 @@ struct hwspinlock_device;* @trylock: make a single attempt to take the lock. returns 0 on * failure and true on success. may _not_ sleep. * @unlock: release the lock. always succeed. may _not_ sleep. +* @bust: optional, platform-specific bust handler, called by hwspinlock +* core to bust a specific lock. * @relax: optional, platform-specific relax handler, called by hwspinlock * core while spinning on a lock, between two successive * invocations of @trylock. may _not_ sleep.
@@ -28,6 +30,7 @@ struct hwspinlock_device;struct hwspinlock_ops {int (*trylock)(struct hwspinlock *lock);void (*unlock)(struct hwspinlock *lock); +int (*bust)(struct hwspinlock *lock,unsigned int id);void (*relax)(struct hwspinlock *lock); };
include/linux/hwspinlock.h +6 -0
@@ -68,6 +68,7 @@ int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int,int __hwspin_trylock (struct hwspinlock *,int ,unsigned long *);void __hwspin_unlock (struct hwspinlock *,int ,unsigned long *);int of_hwspin_lock_get_id_byname (struct device_node *np,const char *name); +int hwspin_lock_bust (struct hwspinlock *hwlock,unsigned int id);int devm_hwspin_lock_free (struct device *dev,struct hwspinlock *hwlock);struct hwspinlock *devm_hwspin_lock_request (struct device *dev); struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev,
@@ -127,6 +128,11 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { } +static inline int hwspin_lock_bust (struct hwspinlock *hwlock,unsigned int id) +{ +return 0 ; +} +static inline int of_hwspin_lock_get_id (struct device_node *np,int index) {return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 34/186 ionic: fix potential irq name truncation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shannon Nelson <[email protected]>
[ Upstream commit 3eb76e71b16e8ba5277bf97617aef51f5e64dbe4 ]
Address a warning about potential string truncation based on the string buffer sizes. We can add some hints to the string format specifier to set limits on the resulting possible string to squelch the complaints.
--- drivers/net/ethernet/pensando/ionic/ionic_lif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/pensando/ionic/ionic_lif.c +1 -1
@@ -210,7 +210,7 @@ static int ionic_request_irq(struct ionic_lif *lif, struct ionic_qcq *qcq) name =dev_name (dev);snprintf (intr->name,sizeof (intr->name), -"%s-%s-%s" ,IONIC_DRV_NAME , name, q->name); +"%.5s-%.16s-%.8s" ,IONIC_DRV_NAME , name, q->name);return devm_request_irq (dev, intr->vector, ionic_isr,0 , intr->name, &qcq->napi);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 35/186 usbip: Dont submit special requests twice
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Holesch <[email protected]>
[ Upstream commit 8b6b386f9aa936ed0c190446c71cf59d4a507690 ]
Skip submitting URBs, when identical requests were already sent in tweak_special_requests(). Instead call the completion handler directly to return the result of the URB.
Even though submitting those requests twice should be harmless, there are USB devices that react poorly to some duplicated requests.
One example is the ChipIdea controller implementation in U-Boot: The second SET_CONFIGURATION request makes U-Boot disable and re-enable all endpoints. Re-enabling an endpoint in the ChipIdea controller, however, was broken until U-Boot commit b272c8792502 ("usb: ci: Fix gadget reinit").
--- drivers/usb/usbip/stub_rx.c | 77 ++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 27 deletions(-)
drivers/usb/usbip/stub_rx.c +50 -27
@@ -144,53 +144,62 @@ static int tweak_set_configuration_cmd(struct urb *urb)if (err && err != -ENODEV )dev_err (&sdev->udev->dev,"can't set config #%d, error %d\n" , config, err); -return 0 ; +return err; }static int tweak_reset_device_cmd (struct urb *urb) {struct stub_priv *priv = (struct stub_priv *) urb->context;struct stub_device *sdev = priv->sdev; +int err;dev_info (&urb->dev->dev,"usb_queue_reset_device\n" ); -if (usb_lock_device_for_reset (sdev->udev,NULL ) <0 ) { + err =usb_lock_device_for_reset (sdev->udev,NULL ); +if (err <0 ) {dev_err (&urb->dev->dev,"could not obtain lock to reset device\n" ); -return 0 ; +return err; } -usb_reset_device (sdev->udev); + err =usb_reset_device (sdev->udev);usb_unlock_device (sdev->udev); -return 0 ; +return err; }/* * clear_halt, set_interface, and set_configuration require special tricks. +* Returns 1 if request was tweaked, 0 otherwise. */ -static void tweak_special_requests (struct urb *urb) +static int tweak_special_requests (struct urb *urb) { +int err; +if (!urb || !urb->setup_packet) -return ; +return 0 ;if (usb_pipetype (urb->pipe) !=PIPE_CONTROL ) -return ; +return 0 ;if (is_clear_halt_cmd (urb))/* tweak clear_halt */ -tweak_clear_halt_cmd (urb); + err =tweak_clear_halt_cmd (urb);else if (is_set_interface_cmd (urb))/* tweak set_interface */ -tweak_set_interface_cmd (urb); + err =tweak_set_interface_cmd (urb);else if (is_set_configuration_cmd (urb))/* tweak set_configuration */ -tweak_set_configuration_cmd (urb); + err =tweak_set_configuration_cmd (urb);else if (is_reset_device_cmd (urb)) -tweak_reset_device_cmd (urb); -else + err =tweak_reset_device_cmd (urb); +else {usbip_dbg_stub_rx ("no need to tweak\n" ); +return 0 ; + } + +return !err; }/*
@@ -468,6 +477,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,int support_sg =1 ;int np =0 ;int ret, i; +int is_tweaked;if (pipe ==-1 )return ;
@@ -580,8 +590,11 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, priv->urbs[i]->pipe = pipe; priv->urbs[i]->complete = stub_complete; -/* no need to submit an intercepted request, but harmless? */ -tweak_special_requests (priv->urbs[i]); +/* +* all URBs belong to a single PDU, so a global is_tweaked flag is +* enough +*/ + is_tweaked =tweak_special_requests (priv->urbs[i]);masking_bogus_flags (priv->urbs[i]); }
@@ -594,22 +607,32 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,/* urb is now ready to submit */ for (i =0 ; i < priv->num_urbs; i++) { - ret =usb_submit_urb (priv->urbs[i],GFP_KERNEL ); +if (!is_tweaked) { + ret =usb_submit_urb (priv->urbs[i],GFP_KERNEL ); -if (ret ==0 ) -usbip_dbg_stub_rx ("submit urb ok, seqnum %u\n" , - pdu->base.seqnum); -else { -dev_err (&udev->dev,"submit_urb error, %d\n" , ret); -usbip_dump_header (pdu); -usbip_dump_urb (priv->urbs[i]); +if (ret ==0 ) +usbip_dbg_stub_rx ("submit urb ok, seqnum %u\n" , + pdu->base.seqnum); +else { +dev_err (&udev->dev,"submit_urb error, %d\n" , ret); +usbip_dump_header (pdu); +usbip_dump_urb (priv->urbs[i]); +/* +* Pessimistic. +* This connection will be discarded. +*/ +usbip_event_add (ud,SDEV_EVENT_ERROR_SUBMIT ); +break ; + } + }else {/* -* Pessimistic. -* This connection will be discarded. +* An identical URB was already submitted in +* tweak_special_requests(). Skip submitting this URB to not +* duplicate the request. */ -usbip_event_add (ud,SDEV_EVENT_ERROR_SUBMIT ); -break ; + priv->urbs[i]->status =0 ; +stub_complete (priv->urbs[i]); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 36/186 usb: typec: ucsi: Fix null pointer dereference in trace
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Pandit-Subedi <[email protected]>
[ Upstream commit 99516f76db48e1a9d54cdfed63c1babcee4e71a5 ]
ucsi_register_altmode checks IS_ERR for the alt pointer and treats NULL as valid. When CONFIG_TYPEC_DP_ALTMODE is not enabled, ucsi_register_displayport returns NULL which causes a NULL pointer dereference in trace. Rather than return NULL, call typec_port_register_altmode to register DisplayPort alternate mode as a non-controllable mode when CONFIG_TYPEC_DP_ALTMODE is not enabled.
--- drivers/usb/typec/ucsi/ucsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/typec/ucsi/ucsi.h +1 -1
@@ -365,7 +365,7 @@ ucsi_register_displayport(struct ucsi_connector *con, bool override, int offset, struct typec_altmode_desc *desc) { - return NULL; + return typec_port_register_altmode(con->port, desc); } static inline void
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 37/186 fsnotify: clear PARENT_WATCHED flags lazily
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <[email protected]>
[ Upstream commit 172e422ffea20a89bfdc672741c1aad6fbb5044e ]
In some setups directories can have many (usually negative) dentries. Hence __fsnotify_update_child_dentry_flags() function can take a significant amount of time. Since the bulk of this function happens under inode->i_lock this causes a significant contention on the lock when we remove the watch from the directory as the __fsnotify_update_child_dentry_flags() call from fsnotify_recalc_mask() races with __fsnotify_update_child_dentry_flags() calls from __fsnotify_parent() happening on children. This can lead upto softlockup reports reported by users.
Fix the problem by calling fsnotify_update_children_dentry_flags() to set PARENT_WATCHED flags only when parent starts watching children.
When parent stops watching children, clear false positive PARENT_WATCHED flags lazily in __fsnotify_parent() for each accessed child.
--- fs/notify/fsnotify.c | 31 +++++++++++++++++++++---------- fs/notify/fsnotify.h | 2 +- fs/notify/mark.c | 32 +++++++++++++++++++++++++++++--- include/linux/fsnotify_backend.h | 8 +++++--- 4 files changed, 56 insertions(+), 17 deletions(-)
fs/notify/fsnotify.c +21 -10
@@ -103,17 +103,13 @@ void fsnotify_sb_delete(struct super_block *sb)* parent cares. Thus when an event happens on a child it can quickly tell * if there is a need to find a parent and send the event to the parent. */ -void __fsnotify_update_child_dentry_flags (struct inode *inode) +void fsnotify_set_children_dentry_flags (struct inode *inode) {struct dentry *alias; -int watched;if (!S_ISDIR (inode->i_mode))return ; -/* determine if the children should tell inode about their events */ - watched =fsnotify_inode_watches_children (inode); -spin_lock (&inode->i_lock);/* run all of the dentries associated with this inode. Since this is a * directory, there damn well better only be one item on this list */
@@ -129,10 +125,7 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)continue ;spin_lock_nested (&child->d_lock,DENTRY_D_LOCK_NESTED ); -if (watched) - child->d_flags |=DCACHE_FSNOTIFY_PARENT_WATCHED ; -else - child->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED ; + child->d_flags |=DCACHE_FSNOTIFY_PARENT_WATCHED ;spin_unlock (&child->d_lock); }spin_unlock (&alias->d_lock);
@@ -140,6 +133,24 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)spin_unlock (&inode->i_lock); } +/* +* Lazily clear false positive PARENT_WATCHED flag for child whose parent had +* stopped watching children. +*/ +static void fsnotify_clear_child_dentry_flag (struct inode *pinode, +struct dentry *dentry) +{ +spin_lock (&dentry->d_lock); +/* +* d_lock is a sufficient barrier to prevent observing a non-watched +* parent state from before the fsnotify_set_children_dentry_flags() +* or fsnotify_update_flags() call that had set PARENT_WATCHED. +*/ +if (!fsnotify_inode_watches_children (pinode)) + dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED ; +spin_unlock (&dentry->d_lock); +} +/* Are inode/sb/mount interested in parent and name info with this event? */ static bool fsnotify_event_needs_parent (struct inode *inode,struct mount *mnt,__u32 mask)
@@ -208,7 +219,7 @@ int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, p_inode = parent->d_inode; p_mask =fsnotify_inode_watches_children (p_inode);if (unlikely (parent_watched && !p_mask)) -__fsnotify_update_child_dentry_flags (p_inode); +fsnotify_clear_child_dentry_flag (p_inode, dentry);/* * Include parent/name in notification either if some notification
fs/notify/fsnotify.h +1 -1
@@ -74,7 +74,7 @@ static inline void fsnotify_clear_marks_by_sb(struct super_block *sb)* update the dentry->d_flags of all of inode's children to indicate if inode cares * about events that happen to its children. */ -extern void __fsnotify_update_child_dentry_flags (struct inode *inode); +extern void fsnotify_set_children_dentry_flags (struct inode *inode);extern struct kmem_cache *fsnotify_mark_connector_cachep;
fs/notify/mark.c +29 -3
@@ -176,6 +176,24 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)return fsnotify_update_iref (conn, want_iref); } +static bool fsnotify_conn_watches_children ( +struct fsnotify_mark_connector *conn) +{ +if (conn->type !=FSNOTIFY_OBJ_TYPE_INODE ) +return false; + +return fsnotify_inode_watches_children (fsnotify_conn_inode (conn)); +} + +static void fsnotify_conn_set_children_dentry_flags ( +struct fsnotify_mark_connector *conn) +{ +if (conn->type !=FSNOTIFY_OBJ_TYPE_INODE ) +return ; + +fsnotify_set_children_dentry_flags (fsnotify_conn_inode (conn)); +} +/* * Calculate mask of events for a list of marks. The caller must make sure * connector and connector->obj cannot disappear under us. Callers achieve
@@ -184,15 +202,23 @@ static void *__fsnotify_recalc_mask(struct fsnotify_mark_connector *conn)*/ void fsnotify_recalc_mask (struct fsnotify_mark_connector *conn) { +bool update_children; +if (!conn)return ;spin_lock (&conn->lock); + update_children = !fsnotify_conn_watches_children (conn);__fsnotify_recalc_mask (conn); + update_children &=fsnotify_conn_watches_children (conn);spin_unlock (&conn->lock); -if (conn->type ==FSNOTIFY_OBJ_TYPE_INODE ) -__fsnotify_update_child_dentry_flags ( -fsnotify_conn_inode (conn)); +/* +* Set children's PARENT_WATCHED flags only if parent started watching. +* When parent stops watching, we clear false positive PARENT_WATCHED +* flags lazily in __fsnotify_parent(). +*/ +if (update_children) +fsnotify_conn_set_children_dentry_flags (conn); }/* Free all connectors queued for freeing once SRCU period ends */
include/linux/fsnotify_backend.h +5 -3
@@ -563,12 +563,14 @@ static inline __u32 fsnotify_parent_needed_mask(__u32 mask)static inline int fsnotify_inode_watches_children (struct inode *inode) { +__u32 parent_mask =READ_ONCE (inode->i_fsnotify_mask); +/* FS_EVENT_ON_CHILD is set if the inode may care */ -if (!(inode->i_fsnotify_mask &FS_EVENT_ON_CHILD )) +if (!(parent_mask &FS_EVENT_ON_CHILD ))return 0 ;/* this inode might care about child events, does it care about the * specific set of events that can happen on a child? */ -return inode->i_fsnotify_mask &FS_EVENTS_POSS_ON_CHILD ; +return parent_mask &FS_EVENTS_POSS_ON_CHILD ; }/*
@@ -582,7 +584,7 @@ static inline void fsnotify_update_flags(struct dentry *dentry)/* * Serialisation of setting PARENT_WATCHED on the dentries is provided * by d_lock. If inotify_inode_watched changes after we have taken -* d_lock, the following __fsnotify_update_child_dentry_flags call will +* d_lock, the following fsnotify_set_children_dentry_flags call will * find our entry, so it will spin until we complete here, and update * us with the new state. */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 38/186 smack: tcp: ipv4, fix incorrect labeling
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Casey Schaufler <[email protected]>
[ Upstream commit 2fe209d0ad2e2729f7e22b9b31a86cc3ff0db550 ]
Currently, Smack mirrors the label of incoming tcp/ipv4 connections:
when a label 'foo' connects to a label 'bar' with tcp/ipv4, 'foo' always gets 'foo' in returned ipv4 packets. So,
1) returned packets are incorrectly labeled ('foo' instead of 'bar')
2) 'bar' can write to 'foo' without being authorized to write.
Here is a scenario how to see this:
* Take two machines, let's call them C and S,
with active Smack in the default state
(no settings, no rules, no labeled hosts, only builtin labels)
* At S, add Smack rule 'foo bar w'
(labels 'foo' and 'bar' are instantiated at S at this moment)
* At S, at label 'bar', launch a program
that listens for incoming tcp/ipv4 connections
* From C, at label 'foo', connect to the listener at S. (label 'foo' is instantiated at C at this moment) Connection succeedes and works.
* Send some data in both directions.
* Collect network traffic of this connection.
All packets in both directions are labeled with the CIPSO of the label 'foo'. Hence, label 'bar' writes to 'foo' without being authorized, and even without ever being known at C.
If anybody cares: exactly the same happens with DCCP.
This behavior 1st manifested in release 2.6.29.4 (see Fixes below) and it looks unintentional. At least, no explanation was provided.
I changed returned packes label into the 'bar', to bring it into line with the Smack documentation claims.
--- security/smack/smack_lsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
security/smack/smack_lsm.c +1 -1
@@ -4228,7 +4228,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,rcu_read_unlock ();if (hskp ==NULL ) - rc =netlbl_req_setattr (req, &skp->smk_netlabel); + rc =netlbl_req_setattr (req, &ssp->smk_out->smk_netlabel);else netlbl_req_delattr (req);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 39/186 drm/meson: plane: Add error handling
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoran Liu <[email protected]>
[ Upstream commit 3c28b239620e249b68beeca17f429e317fa6b8d4 ]
This patch adds robust error handling to the meson_plane_create function in drivers/gpu/drm/meson/meson_plane.c. The function previously lacked proper handling for potential failure scenarios of the drm_universal_plane_init call.
--- drivers/gpu/drm/meson/meson_plane.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/gpu/drm/meson/meson_plane.c +11 -6
@@ -529,6 +529,7 @@ int meson_plane_create(struct meson_drm *priv)struct meson_plane *meson_plane;struct drm_plane *plane;const uint64_t *format_modifiers = format_modifiers_default; +int ret; meson_plane =devm_kzalloc (priv->drm->dev,sizeof (*meson_plane),GFP_KERNEL );
@@ -543,12 +544,16 @@ int meson_plane_create(struct meson_drm *priv)else if (meson_vpu_is_compatible (priv,VPU_COMPATIBLE_G12A )) format_modifiers = format_modifiers_afbc_g12a; -drm_universal_plane_init (priv->drm, plane,0xFF , - &meson_plane_funcs, - supported_drm_formats, -ARRAY_SIZE (supported_drm_formats), - format_modifiers, -DRM_PLANE_TYPE_PRIMARY ,"meson_primary_plane" ); + ret =drm_universal_plane_init (priv->drm, plane,0xFF , + &meson_plane_funcs, + supported_drm_formats, +ARRAY_SIZE (supported_drm_formats), + format_modifiers, +DRM_PLANE_TYPE_PRIMARY ,"meson_primary_plane" ); +if (ret) { +devm_kfree (priv->drm->dev, meson_plane); +return ret; + }drm_plane_helper_add (plane, &meson_plane_helper_funcs);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 40/186 wifi: cfg80211: make hash table duplicates more survivable
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 7f12e26a194d0043441f870708093d9c2c3bad7d ]
Jiazi Li reported that they occasionally see hash table duplicates as evidenced by the WARN_ON() in rb_insert_bss() in this code. It isn't clear how that happens, nor have I been able to reproduce it, but if it does happen, the kernel crashes later, when it tries to unhash the entry that's now not hashed.
Try to make this situation more survivable by removing the BSS from the list(s) as well, that way it's fully leaked here (as had been the intent in the hash insert error path), and no longer reachable through the list(s) so it shouldn't be unhashed again later.
--- net/wireless/scan.c | 46 +++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-)
net/wireless/scan.c +34 -12
@@ -1510,7 +1510,7 @@ struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, }EXPORT_SYMBOL (cfg80211_get_bss); -static void rb_insert_bss (struct cfg80211_registered_device *rdev, +static bool rb_insert_bss (struct cfg80211_registered_device *rdev,struct cfg80211_internal_bss *bss) {struct rb_node **p = &rdev->bss_tree.rb_node;
@@ -1526,7 +1526,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev,if (WARN_ON (!cmp)) {/* will sort of leak this BSS */ -return ; +return false; }if (cmp <0 )
@@ -1537,6 +1537,7 @@ static void rb_insert_bss(struct cfg80211_registered_device *rdev,rb_link_node (&bss->rbn, parent, p);rb_insert_color (&bss->rbn, &rdev->bss_tree); +return true; } static struct cfg80211_internal_bss *
@@ -1563,6 +1564,34 @@ rb_find_bss(struct cfg80211_registered_device *rdev,return NULL ; } +static void cfg80211_insert_bss (struct cfg80211_registered_device *rdev, +struct cfg80211_internal_bss *bss) +{ +lockdep_assert_held (&rdev->bss_lock); + +if (!rb_insert_bss (rdev, bss)) +return ; +list_add_tail (&bss->list, &rdev->bss_list); + rdev->bss_entries++; +} + +static void cfg80211_rehash_bss (struct cfg80211_registered_device *rdev, +struct cfg80211_internal_bss *bss) +{ +lockdep_assert_held (&rdev->bss_lock); + +rb_erase (&bss->rbn, &rdev->bss_tree); +if (!rb_insert_bss (rdev, bss)) { +list_del (&bss->list); +if (!list_empty (&bss->hidden_list)) +list_del_init (&bss->hidden_list); +if (!list_empty (&bss->pub.nontrans_list)) +list_del_init (&bss->pub.nontrans_list); + rdev->bss_entries--; + } + rdev->bss_generation++; +} +static bool cfg80211_combine_bsses (struct cfg80211_registered_device *rdev,struct cfg80211_internal_bss *new) {
@@ -1838,9 +1867,7 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,bss_ref_get (rdev, pbss); } -list_add_tail (&new->list, &rdev->bss_list); - rdev->bss_entries++; -rb_insert_bss (rdev, new); +cfg80211_insert_bss (rdev, new); found = new; }
@@ -2702,10 +2729,7 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,if (!WARN_ON (!__cfg80211_unlink_bss (rdev, new))) rdev->bss_generation++; } - -rb_erase (&cbss->rbn, &rdev->bss_tree); -rb_insert_bss (rdev, cbss); - rdev->bss_generation++; +cfg80211_rehash_bss (rdev, cbss);list_for_each_entry_safe (nontrans_bss, tmp, &cbss->pub.nontrans_list,
@@ -2713,9 +2737,7 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev, bss =container_of (nontrans_bss, struct cfg80211_internal_bss, pub); bss->pub.channel = chan; -rb_erase (&bss->rbn, &rdev->bss_tree); -rb_insert_bss (rdev, bss); - rdev->bss_generation++; +cfg80211_rehash_bss (rdev, bss); } done:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 41/186 block: remove the blk_flush_integrity call in blk_integrity_unregister
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit e8bc14d116aeac8f0f133ec8d249acf4e0658da7 ]
Now that there are no indirect calls for PI processing there is no way to dereference a NULL pointer here. Additionally drivers now always freeze the queue (or in case of stacking drivers use their internal equivalent) around changing the integrity profile.
This is effectively a revert of commit 3df49967f6f1 ("block: flush the integrity workqueue in blk_integrity_unregister").
--- block/blk-integrity.c | 2 -- 1 file changed, 2 deletions(-)
block/blk-integrity.c +0 -2
@@ -431,8 +431,6 @@ void blk_integrity_unregister(struct gendisk *disk)if (!bi->profile)return ; -/* ensure all bios are off the integrity workqueue */ -blk_flush_integrity ();blk_queue_flag_clear (QUEUE_FLAG_STABLE_WRITES , disk->queue);memset (bi,0 ,sizeof (*bi)); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 42/186 drm/amd/display: Skip wbscl_set_scaler_filter if filter is null
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit c4d31653c03b90e51515b1380115d1aedad925dd ]
Callers can pass null in filter (i.e. from returned from the function wbscl_get_filter_coeffs_16p) and a null check is added to ensure that is not the case.
This fixes 4 NULL_RETURNS issues reported by Coverity.
--- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +3 -0
@@ -690,6 +690,9 @@ static void wbscl_set_scaler_filter(int pair;uint16_t odd_coef, even_coef; +if (!filter) +return ; +for (phase =0 ; phase < (NUM_PHASES /2 +1 ); phase++) {for (pair =0 ; pair < tap_pairs; pair++) { even_coef = filter[phase * taps +2 * pair];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 43/186 media: uvcvideo: Enforce alignment of frame and interval
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <[email protected]>
[ Upstream commit c8931ef55bd325052ec496f242aea7f6de47dc9c ]
Struct uvc_frame and interval (u32*) are packaged together on streaming->formats on a single contiguous allocation.
Right now they are allocated right after uvc_format, without taking into consideration their required alignment.
This is working fine because both structures have a field with a pointer, but it will stop working when the sizeof() of any of those structs is not a multiple of the sizeof(void*).
Enforce that alignment during the allocation.
--- drivers/media/usb/uvc/uvc_driver.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/media/usb/uvc/uvc_driver.c +14 -4
@@ -948,16 +948,26 @@ static int uvc_parse_streaming(struct uvc_device *dev, goto error; } - size = nformats *sizeof (*format) + nframes *sizeof (*frame) +/* +* Allocate memory for the formats, the frames and the intervals, +* plus any required padding to guarantee that everything has the +* correct alignment. +*/ + size = nformats *sizeof (*format); + size = ALIGN(size, __alignof__(*frame)) + nframes * sizeof(*frame); + size = ALIGN(size, __alignof__(*interval)) + nintervals *sizeof (*interval); + format =kzalloc (size,GFP_KERNEL ); -if (format ==NULL ) { +if (!format) { ret = -ENOMEM ; goto error; } - frame = (struct uvc_frame *)&format[nformats]; - interval = (u32 *)&frame[nframes]; + frame = (void *)format + nformats *sizeof (*format); + frame = PTR_ALIGN(frame, __alignof__(*frame)); + interval = (void *)frame + nframes *sizeof (*frame); + interval = PTR_ALIGN(interval, __alignof__(*interval)); streaming->format = format; streaming->nformats = nformats;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 44/186 block: initialize integrity buffer to zero before writing it to media
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
commit 899ee2c3829c5ac14bfc7d3c4a5846c0b709b78f upstream.
Metadata added by bio_integrity_prep is using plain kmalloc, which leads to random kernel memory being written media. For PI metadata this is limited to the app tag that isn't used by kernel generated metadata, but for non-PI metadata the entire buffer leaks kernel memory.
Fix this by adding the __GFP_ZERO flag to allocations for writes.
--- block/bio-integrity.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
block/bio-integrity.c +10 -1
@@ -216,6 +216,7 @@ bool bio_integrity_prep(struct bio *bio)unsigned int bytes, offset, i;unsigned int intervals;blk_status_t status; +gfp_t gfp =GFP_NOIO ;if (!bi)return true;
@@ -238,12 +239,20 @@ bool bio_integrity_prep(struct bio *bio)if (!bi->profile->generate_fn || !(bi->flags &BLK_INTEGRITY_GENERATE ))return true; + +/* +* Zero the memory allocated to not leak uninitialized kernel +* memory to disk. For PI this only affects the app tag, but +* for non-integrity metadata it affects the entire metadata +* buffer. +*/ + gfp |= __GFP_ZERO; } intervals =bio_integrity_intervals (bi,bio_sectors (bio));/* Allocate kernel buffer for protection data */ len = intervals * bi->tuple_size; - buf =kmalloc (len,GFP_NOIO | q->bounce_gfp); + buf =kmalloc (len, gfp | q->bounce_gfp); status =BLK_STS_RESOURCE ;if (unlikely (buf ==NULL )) {printk (KERN_ERR "could not allocate integrity buffer\n" );
Greg Kroah-Hartman
maintainerPATCH 45/186 drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bob Zhou <[email protected]>
commit 50151b7f1c79a09117837eb95b76c2de76841dab upstream.
Check return value and conduct null pointer handling to avoid null pointer dereference.
--- drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 30 +++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +26 -4
@@ -3410,13 +3410,17 @@ static int vega10_find_dpm_states_clocksconst struct vega10_power_state *vega10_ps =cast_const_phw_vega10_power_state (states->pnew_state);struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); -uint32_t sclk = vega10_ps->performance_levels - [vega10_ps->performance_level_count -1 ].gfx_clock;struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); -uint32_t mclk = vega10_ps->performance_levels - [vega10_ps->performance_level_count -1 ].mem_clock; +uint32_t sclk, mclk;uint32_t i; +if (vega10_ps ==NULL ) +return -EINVAL ; + sclk = vega10_ps->performance_levels + [vega10_ps->performance_level_count -1 ].gfx_clock; + mclk = vega10_ps->performance_levels + [vega10_ps->performance_level_count -1 ].mem_clock; +for (i =0 ; i < sclk_table->count; i++) {if (sclk == sclk_table->dpm_levels[i].value)break ;
@@ -3723,6 +3727,9 @@ static int vega10_generate_dpm_level_enacast_const_phw_vega10_power_state (states->pnew_state);int i; +if (vega10_ps ==NULL ) +return -EINVAL ; +PP_ASSERT_WITH_CODE (!vega10_trim_dpm_states (hwmgr, vega10_ps),"Attempt to Trim DPM States Failed!" , return -1 );
@@ -4858,6 +4865,9 @@ static int vega10_check_states_equal(str psa =cast_const_phw_vega10_power_state (pstate1); psb =cast_const_phw_vega10_power_state (pstate2); +if (psa ==NULL || psb ==NULL ) +return -EINVAL ; +/* If the two states don't even have the same number of performance levels they cannot be the same state. */ if (psa->performance_level_count != psb->performance_level_count) { *equal = false;
@@ -4983,6 +4993,8 @@ static int vega10_set_sclk_od(struct pp_return -EINVAL ; vega10_ps =cast_phw_vega10_power_state (&ps->hardware); +if (vega10_ps ==NULL ) +return -EINVAL ; vega10_ps->performance_levels [vega10_ps->performance_level_count - 1].gfx_clock =
@@ -5034,6 +5046,8 @@ static int vega10_set_mclk_od(struct pp_return -EINVAL ; vega10_ps =cast_phw_vega10_power_state (&ps->hardware); +if (vega10_ps ==NULL ) +return -EINVAL ; vega10_ps->performance_levels [vega10_ps->performance_level_count - 1].mem_clock =
@@ -5269,6 +5283,9 @@ static void vega10_odn_update_power_statreturn ; vega10_ps =cast_phw_vega10_power_state (&ps->hardware); +if (vega10_ps ==NULL ) +return ; + max_level = vega10_ps->performance_level_count -1 ; if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5291,6 +5308,9 @@ static void vega10_odn_update_power_stat ps = (struct pp_power_state *)((unsigned long )(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps -1 )); vega10_ps =cast_phw_vega10_power_state (&ps->hardware); +if (vega10_ps ==NULL ) +return ; + max_level = vega10_ps->performance_level_count -1 ; if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5481,6 +5501,8 @@ static int vega10_get_performance_level(return -EINVAL ; ps =cast_const_phw_vega10_power_state (state); +if (ps ==NULL ) +return -EINVAL ; i = index > ps->performance_level_count -1 ? ps->performance_level_count -1 : index;
Greg Kroah-Hartman
maintainerPATCH 46/186 bpf, cgroups: Fix cgroup v2 fallback on v1/v2 mixed mode
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Connor O'Brien <[email protected]>
From: Daniel Borkmann <[email protected]>
commit 8520e224f547cd070c7c8f97b1fc6d58cff7ccaa upstream.
Fix cgroup v1 interference when non-root cgroup v2 BPF programs are used. Back in the days, commit bd1060a1d671 ("sock, cgroup: add sock->sk_cgroup") embedded per-socket cgroup information into sock->sk_cgrp_data and in order to save 8 bytes in struct sock made both mutually exclusive, that is, when cgroup v1 socket tagging (e.g. net_cls/net_prio) is used, then cgroup v2 falls back to the root cgroup in sock_cgroup_ptr() (&cgrp_dfl_root.cgrp).
The assumption made was "there is no reason to mix the two and this is in line with how legacy and v2 compatibility is handled" as stated in bd1060a1d671. However, with Kubernetes more widely supporting cgroups v2 as well nowadays, this assumption no longer holds, and the possibility of the v1/v2 mixed mode with the v2 root fallback being hit becomes a real security issue.
Many of the cgroup v2 BPF programs are also used for policy enforcement, just to pick _one_ example, that is, to programmatically deny socket related system calls like connect(2) or bind(2). A v2 root fallback would implicitly cause a policy bypass for the affected Pods.
In production environments, we have recently seen this case due to various
circumstances: i) a different 3rd party agent and/or ii) a container runtime such as [0] in the user's environment configuring legacy cgroup v1 net_cls tags, which triggered implicitly mentioned root fallback. Another case is Kubernetes projects like kind [1] which create Kubernetes nodes in a container and also add cgroup namespaces to the mix, meaning programs which are attached to the cgroup v2 root of the cgroup namespace get attached to a non-root cgroup v2 path from init namespace point of view. And the latter's root is out of reach for agents on a kind Kubernetes node to configure. Meaning, any entity on the node setting cgroup v1 net_cls tag will trigger the bypass despite cgroup v2 BPF programs attached to the namespace root.
Generally, this mutual exclusiveness does not hold anymore in today's user environments and makes cgroup v2 usage from BPF side fragile and unreliable. This fix adds proper struct cgroup pointer for the cgroup v2 case to struct sock_cgroup_data in order to address these issues; this implicitly also fixes the tradeoffs being made back then with regards to races and refcount leaks as stated in bd1060a1d671, and removes the fallback, so that cgroup v2 BPF programs always operate as expected.
[0] https://github.com/nestybox/sysbox/
[1] https://kind.sigs.k8s.io/
--- include/linux/cgroup-defs.h | 107 ++++++++++--------------------------------- include/linux/cgroup.h | 22 -------- kernel/cgroup/cgroup.c | 50 ++++---------------- net/core/netclassid_cgroup.c | 7 -- net/core/netprio_cgroup.c | 10 ---- 5 files changed, 41 insertions(+), 155 deletions(-)
include/linux/cgroup-defs.h +27 -80
@@ -764,107 +764,54 @@ static inline void cgroup_threadgroup_ch* sock_cgroup_data is embedded at sock->sk_cgrp_data and contains * per-socket cgroup information except for memcg association. * -* On legacy hierarchies, net_prio and net_cls controllers directly set -* attributes on each sock which can then be tested by the network layer. -* On the default hierarchy, each sock is associated with the cgroup it was -* created in and the networking layer can match the cgroup directly. -* -* To avoid carrying all three cgroup related fields separately in sock, -* sock_cgroup_data overloads (prioidx, classid) and the cgroup pointer. -* On boot, sock_cgroup_data records the cgroup that the sock was created -* in so that cgroup2 matches can be made; however, once either net_prio or -* net_cls starts being used, the area is overriden to carry prioidx and/or -* classid. The two modes are distinguished by whether the lowest bit is -* set. Clear bit indicates cgroup pointer while set bit prioidx and -* classid. -* -* While userland may start using net_prio or net_cls at any time, once -* either is used, cgroup2 matching no longer works. There is no reason to -* mix the two and this is in line with how legacy and v2 compatibility is -* handled. On mode switch, cgroup references which are already being -* pointed to by socks may be leaked. While this can be remedied by adding -* synchronization around sock_cgroup_data, given that the number of leaked -* cgroups is bound and highly unlikely to be high, this seems to be the -* better trade-off. +* On legacy hierarchies, net_prio and net_cls controllers directly +* set attributes on each sock which can then be tested by the network +* layer. On the default hierarchy, each sock is associated with the +* cgroup it was created in and the networking layer can match the +* cgroup directly. */ struct sock_cgroup_data { -union { -#ifdef __LITTLE_ENDIAN -struct { -u8 is_data :1 ; -u8 no_refcnt :1 ; -u8 unused :6 ; -u8 padding; -u16 prioidx; -u32 classid; - } __packed; -#else -struct { -u32 classid; -u16 prioidx; -u8 padding; -u8 unused :6 ; -u8 no_refcnt :1 ; -u8 is_data :1 ; - } __packed; +struct cgroup *cgroup;/* v2 */ +#ifdef CONFIG_CGROUP_NET_CLASSID +u32 classid;/* v1 */ +#endif +#ifdef CONFIG_CGROUP_NET_PRIO +u16 prioidx;/* v1 */ #endif -u64 val; - }; }; -/* -* There's a theoretical window where the following accessors race with -* updaters and return part of the previous pointer as the prioidx or -* classid. Such races are short-lived and the result isn't critical. -*/ static inline u16 sock_cgroup_prioidx (const struct sock_cgroup_data *skcd) { -/* fallback to 1 which is always the ID of the root cgroup */ -return (skcd->is_data &1 ) ? skcd->prioidx :1 ; +#ifdef CONFIG_CGROUP_NET_PRIO +return READ_ONCE (skcd->prioidx); +#else +return 1 ; +#endif }static inline u32 sock_cgroup_classid (const struct sock_cgroup_data *skcd) { -/* fallback to 0 which is the unconfigured default classid */ -return (skcd->is_data &1 ) ? skcd->classid :0 ; +#ifdef CONFIG_CGROUP_NET_CLASSID +return READ_ONCE (skcd->classid); +#else +return 0 ; +#endif } -/* -* If invoked concurrently, the updaters may clobber each other. The -* caller is responsible for synchronization. -*/ static inline void sock_cgroup_set_prioidx (struct sock_cgroup_data *skcd,u16 prioidx) { -struct sock_cgroup_data skcd_buf = {{ .val =READ_ONCE (skcd->val) }}; - -if (sock_cgroup_prioidx (&skcd_buf) == prioidx) -return ; - -if (!(skcd_buf.is_data &1 )) { - skcd_buf.val =0 ; - skcd_buf.is_data =1 ; - } - - skcd_buf.prioidx = prioidx; -WRITE_ONCE (skcd->val, skcd_buf.val);/* see sock_cgroup_ptr() */ +#ifdef CONFIG_CGROUP_NET_PRIO +WRITE_ONCE (skcd->prioidx, prioidx); +#endif }static inline void sock_cgroup_set_classid (struct sock_cgroup_data *skcd,u32 classid) { -struct sock_cgroup_data skcd_buf = {{ .val =READ_ONCE (skcd->val) }}; - -if (sock_cgroup_classid (&skcd_buf) == classid) -return ; - -if (!(skcd_buf.is_data &1 )) { - skcd_buf.val =0 ; - skcd_buf.is_data =1 ; - } - - skcd_buf.classid = classid; -WRITE_ONCE (skcd->val, skcd_buf.val);/* see sock_cgroup_ptr() */ +#ifdef CONFIG_CGROUP_NET_CLASSID +WRITE_ONCE (skcd->classid, classid); +#endif }#else /* CONFIG_SOCK_CGROUP_DATA */
include/linux/cgroup.h +1 -21
@@ -816,33 +816,13 @@ static inline void cgroup_account_cputim*/ #ifdef CONFIG_SOCK_CGROUP_DATA -#if defined(CONFIG_CGROUP_NET_PRIO ) || defined(CONFIG_CGROUP_NET_CLASSID ) -extern spinlock_t cgroup_sk_update_lock; -#endif - -void cgroup_sk_alloc_disable (void );void cgroup_sk_alloc (struct sock_cgroup_data *skcd);void cgroup_sk_clone (struct sock_cgroup_data *skcd);void cgroup_sk_free (struct sock_cgroup_data *skcd);static inline struct cgroup *sock_cgroup_ptr (struct sock_cgroup_data *skcd) { -#if defined(CONFIG_CGROUP_NET_PRIO ) || defined(CONFIG_CGROUP_NET_CLASSID ) -unsigned long v; - -/* -* @skcd->val is 64bit but the following is safe on 32bit too as we -* just need the lower ulong to be written and read atomically. -*/ - v =READ_ONCE (skcd->val); - -if (v &3 ) -return &cgrp_dfl_root.cgrp; - -return (struct cgroup *)(unsigned long )v ?: &cgrp_dfl_root.cgrp; -#else -return (struct cgroup *)(unsigned long )skcd->val; -#endif +return skcd->cgroup; }#else /* CONFIG_CGROUP_DATA */
kernel/cgroup/cgroup.c +10 -40
84 lines not on this page · raw message
net/core/netclassid_cgroup.c +1 -6
@@ -72,11 +72,8 @@ static int update_classid_sock(const voistruct update_classid_context *ctx = (void *)v;struct socket *sock =sock_from_file (file, &err); -if (sock) { -spin_lock (&cgroup_sk_update_lock); +if (sock)sock_cgroup_set_classid (&sock->sk->sk_cgrp_data, ctx->classid); -spin_unlock (&cgroup_sk_update_lock); - }if (--ctx->batch ==0 ) { ctx->batch =UPDATE_CLASSID_BATCH ;return n +1 ;
@@ -122,8 +119,6 @@ static int write_classid(struct cgroup_sstruct css_task_iter it;struct task_struct *p; -cgroup_sk_alloc_disable (); - cs->classid = (u32 )value;css_task_iter_start (css,0 , &it);
net/core/netprio_cgroup.c +2 -8
@@ -207,8 +207,6 @@ static ssize_t write_priomap(struct kernif (!dev)return -ENODEV ; -cgroup_sk_alloc_disable (); -rtnl_lock (); ret =netprio_set_prio (of_css (of), dev, prio);
@@ -222,12 +220,10 @@ static int update_netprio(const void *v, {int err;struct socket *sock =sock_from_file (file, &err); -if (sock) { -spin_lock (&cgroup_sk_update_lock); + +if (sock)sock_cgroup_set_prioidx (&sock->sk->sk_cgrp_data, (unsigned long )v); -spin_unlock (&cgroup_sk_update_lock); - }return 0 ; }
@@ -236,8 +232,6 @@ static void net_prio_attach(struct cgroustruct task_struct *p;struct cgroup_subsys_state *css; -cgroup_sk_alloc_disable (); -cgroup_taskset_for_each (p, css, tset) {void *v = (void *)(unsigned long )css->id;
Greg Kroah-Hartman
maintainerPATCH 47/186 net: set SOCK_RCU_FREE before inserting socket into hashtable
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislav Fomichev <[email protected]>
commit 871019b22d1bcc9fab2d1feba1b9a564acbb6e99 upstream.
We've started to see the following kernel traces:
WARNING: CPU: 83 PID: 0 at net/core/filter.c:6641 sk_lookup+0x1bd/0x1d0 Call Trace: <IRQ> __bpf_skc_lookup+0x10d/0x120 bpf_sk_lookup+0x48/0xd0 bpf_sk_lookup_tcp+0x19/0x20 bpf_prog_<redacted>+0x37c/0x16a3 cls_bpf_classify+0x205/0x2e0 tcf_classify+0x92/0x160 __netif_receive_skb_core+0xe52/0xf10 __netif_receive_skb_list_core+0x96/0x2b0 napi_complete_done+0x7b5/0xb70 <redacted>_poll+0x94/0xb0 net_rx_action+0x163/0x1d70 __do_softirq+0xdc/0x32e asm_call_irq_on_stack+0x12/0x20 </IRQ> do_softirq_own_stack+0x36/0x50 do_softirq+0x44/0x70
__inet_hash can race with lockless (rcu) readers on the other cpus:
__inet_hash
__sk_nulls_add_node_rcu
<- (bpf triggers here)
sock_set_flag(SOCK_RCU_FREE)
Let's move the SOCK_RCU_FREE part up a bit, before we are inserting the socket into hashtables. Note, that the race is really harmless; the bpf callers are handling this situation (where listener socket doesn't have SOCK_RCU_FREE set) correctly, so the only annoyance is a WARN_ONCE.
More details from Eric regarding SOCK_RCU_FREE timeline:
Commit 3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under synflood") added SOCK_RCU_FREE. At that time, the precise location of sock_set_flag(sk, SOCK_RCU_FREE) did not matter, because the thread calling __inet_hash() owns a reference on sk. SOCK_RCU_FREE was only tested at dismantle time.
Commit 6acc9b432e67 ("bpf: Add helper to retrieve socket in BPF") started checking SOCK_RCU_FREE _after_ the lookup to infer whether the refcount has been taken care of.
--- net/ipv4/inet_hashtables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/inet_hashtables.c +1 -1
@@ -653,6 +653,7 @@ int __inet_hash(struct sock *sk, structif (err) goto unlock; } +sock_set_flag (sk,SOCK_RCU_FREE );if (IS_ENABLED (CONFIG_IPV6 ) && sk->sk_reuseport && sk->sk_family ==AF_INET6 )__sk_nulls_add_node_tail_rcu (sk, &ilb->nulls_head);
@@ -660,7 +661,6 @@ int __inet_hash(struct sock *sk, struct__sk_nulls_add_node_rcu (sk, &ilb->nulls_head);inet_hash2 (hashinfo, sk); ilb->count++; -sock_set_flag (sk,SOCK_RCU_FREE );sock_prot_inuse_add (sock_net (sk), sk->sk_prot,1 ); unlock:spin_unlock (&ilb->lock);
Greg Kroah-Hartman
maintainerPATCH 48/186 virtio_net: Fix napi_skb_cache_put warning
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
commit f8321fa75102246d7415a6af441872f6637c93ab upstream.
After the commit bdacf3e34945 ("net: Use nested-BH locking for napi_alloc_cache.") was merged, the following warning began to appear:
WARNING: CPU: 5 PID: 1 at net/core/skbuff.c:1451 napi_skb_cache_put+0x82/0x4b0 __warn+0x12f/0x340 napi_skb_cache_put+0x82/0x4b0 napi_skb_cache_put+0x82/0x4b0 report_bug+0x165/0x370 handle_bug+0x3d/0x80 exc_invalid_op+0x1a/0x50 asm_exc_invalid_op+0x1a/0x20 __free_old_xmit+0x1c8/0x510 napi_skb_cache_put+0x82/0x4b0 __free_old_xmit+0x1c8/0x510 __free_old_xmit+0x1c8/0x510 __pfx___free_old_xmit+0x10/0x10
The issue arises because virtio is assuming it's running in NAPI context even when it's not, such as in the netpoll case.
To resolve this, modify virtnet_poll_tx() to only set NAPI when budget is available. Same for virtnet_poll_cleantx(), which always assumed that it was in a NAPI context.
--- drivers/net/virtio_net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/virtio_net.c +4 -4
@@ -1497,7 +1497,7 @@ static bool is_xdp_raw_buffer_queue(strureturn false; } -static void virtnet_poll_cleantx (struct receive_queue *rq) +static void virtnet_poll_cleantx (struct receive_queue *rq,int budget) {struct virtnet_info *vi = rq->vq->vdev->priv;unsigned int index =vq2rxq (rq->vq);
@@ -1508,7 +1508,7 @@ static void virtnet_poll_cleantx(structreturn ;if (__netif_tx_trylock (txq)) { -free_old_xmit_skbs (sq, true); +free_old_xmit_skbs (sq, !!budget);__netif_tx_unlock (txq); }
@@ -1525,7 +1525,7 @@ static int virtnet_poll(struct napi_struunsigned int received;unsigned int xdp_xmit =0 ; -virtnet_poll_cleantx (rq); +virtnet_poll_cleantx (rq, budget); received =virtnet_receive (rq, budget, &xdp_xmit);
@@ -1598,7 +1598,7 @@ static int virtnet_poll_tx(struct napi_s txq =netdev_get_tx_queue (vi->dev, index);__netif_tx_lock (txq,raw_smp_processor_id ());virtqueue_disable_cb (sq->vq); -free_old_xmit_skbs (sq, true); +free_old_xmit_skbs (sq, !!budget); opaque =virtqueue_enable_cb_prepare (sq->vq);
Greg Kroah-Hartman
maintainerPATCH 49/186 rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikita Kiryushin <[email protected]>
commit cc5645fddb0ce28492b15520306d092730dffa48 upstream.
There is a possibility of buffer overflow in show_rcu_tasks_trace_gp_kthread() if counters, passed to sprintf() are huge. Counter numbers, needed for this are unrealistically high, but buffer overflow is still possible.
Use snprintf() with buffer size instead of sprintf().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- kernel/rcu/tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/rcu/tasks.h +1 -1
@@ -1240,7 +1240,7 @@ static void show_rcu_tasks_trace_gp_kthr {char buf[64 ]; -sprintf (buf,"N%d h:%lu/%lu/%lu" ,atomic_read (&trc_n_readers_need_end), +snprintf (buf,sizeof (buf),"N%d h:%lu/%lu/%lu" ,atomic_read (&trc_n_readers_need_end),data_race (n_heavy_reader_ofl_updates),data_race (n_heavy_reader_updates),data_race (n_heavy_reader_attempts));
Greg Kroah-Hartman
maintainerPATCH 50/186 udf: Limit file size to 4TB
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit c2efd13a2ed4f29bf9ef14ac2fbb7474084655f8 upstream.
UDF disk format supports in principle file sizes up to 1<<64-1. However the file space (including holes) is described by a linked list of extents, each of which can have at most 1GB. Thus the creation and handling of extents gets unusably slow beyond certain point. Limit the file size to 4TB to avoid locking up the kernel too easily.
--- fs/udf/super.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/udf/super.c +8 -1
@@ -86,6 +86,13 @@ enum {#define UDF_MAX_LVID_NESTING 1000enum {UDF_MAX_LINKS =0xffff }; +/* +* We limit filesize to 4TB. This is arbitrary as the on-disk format supports +* more but because the file space is described by a linked list of extents, +* each of which can have at most 1GB, the creation and handling of extents +* gets unusably slow beyond certain point... +*/ +#define UDF_MAX_FILESIZE (1ULL << 42)/* These are the "meat" - everything else is stuffing */ static int udf_fill_super (struct super_block *,void *,int );
@@ -2301,7 +2308,7 @@ static int udf_fill_super(struct super_b ret = -ENOMEM ; goto error_out; } - sb->s_maxbytes =MAX_LFS_FILESIZE ; + sb->s_maxbytes =UDF_MAX_FILESIZE ; sb->s_max_links =UDF_MAX_LINKS ;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 51/186 ext4: handle redirtying in ext4_bio_write_page()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 04e568a3b31cfbd545c04c8bfc35c20e5ccfce0f upstream.
Since we want to transition transaction commits to use ext4_writepages() for writing back ordered, add handling of page redirtying into ext4_bio_write_page(). Also move buffer dirty bit clearing into the same place other buffer state handling.
--- fs/ext4/page-io.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
fs/ext4/page-io.c +12 -2
@@ -493,6 +493,13 @@ int ext4_bio_write_page(struct ext4_io_s/* A hole? We can safely clear the dirty bit */ if (!buffer_mapped (bh))clear_buffer_dirty (bh); +/* +* Keeping dirty some buffer we cannot write? Make +* sure to redirty the page. This happens e.g. when +* doing writeout for transaction commit. +*/ +if (buffer_dirty (bh) && !PageDirty (page)) +redirty_page_for_writepage (wbc, page);if (io->io_bio)ext4_io_submit (io);continue ;
@@ -500,6 +507,7 @@ int ext4_bio_write_page(struct ext4_io_sif (buffer_new (bh))clear_buffer_new (bh);set_buffer_async_write (bh); +clear_buffer_dirty (bh); nr_to_submit++; }while ((bh = bh->b_this_page) != head);
@@ -542,7 +550,10 @@ int ext4_bio_write_page(struct ext4_io_sprintk_ratelimited (KERN_ERR "%s: ret = %d\n" , __func__, ret);redirty_page_for_writepage (wbc, page);do { -clear_buffer_async_write (bh); +if (buffer_async_write (bh)) { +clear_buffer_async_write (bh); +set_buffer_dirty (bh); + } bh = bh->b_this_page; }while (bh != head); goto unlock;
@@ -555,7 +566,6 @@ int ext4_bio_write_page(struct ext4_io_scontinue ;io_submit_add_bh (io, inode, page, bounce_page, bh); nr_submitted++; -clear_buffer_dirty (bh); }while ((bh = bh->b_this_page) != head); unlock:
Greg Kroah-Hartman
maintainerPATCH 52/186 i2c: Use IS_REACHABLE() for substituting empty ACPI functions
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
commit 71833e79a42178d8a50b5081c98c78ace9325628 upstream.
Replace IS_ENABLED() with IS_REACHABLE() to substitute empty stubs for:
i2c_acpi_get_i2c_resource()
i2c_acpi_client_count()
i2c_acpi_find_bus_speed()
i2c_acpi_new_device_by_fwnode()
i2c_adapter *i2c_acpi_find_adapter_by_handle()
i2c_acpi_waive_d0_probe()commit f17c06c6608a ("i2c: Fix conditional for substituting empty ACPI functions") partially fixed this conditional to depend on CONFIG_I2C, but used IS_ENABLED(), which is wrong since CONFIG_I2C is tristate.
CONFIG_ACPI is boolean but let's also change it to use IS_REACHABLE() to future-proof it against becoming tristate.
Somehow despite testing various combinations of CONFIG_I2C and CONFIG_ACPI we missed the combination CONFIG_I2C=m, CONFIG_ACPI=y.
--- include/linux/i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/i2c.h +1 -1
@@ -991,7 +991,7 @@ static inline int of_i2c_get_board_info(struct acpi_resource ;struct acpi_resource_i2c_serialbus ; -#if IS_ENABLED (CONFIG_ACPI ) &&IS_ENABLED (CONFIG_I2C ) +#if IS_REACHABLE (CONFIG_ACPI ) &&IS_REACHABLE (CONFIG_I2C )bool i2c_acpi_get_i2c_resource (struct acpi_resource *ares,struct acpi_resource_i2c_serialbus **i2c);u32 i2c_acpi_find_bus_speed (struct device *dev);
Greg Kroah-Hartman
maintainerPATCH 53/186 bpf, cgroup: Assign cgroup in cgroup_sk_alloc when called from interrupt
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Connor O'Brien <[email protected]>
From: Daniel Borkmann <[email protected]>
commit 78cc316e9583067884eb8bd154301dc1e9ee945c upstream.
If cgroup_sk_alloc() is called from interrupt context, then just assign the root cgroup to skcd->cgroup. Prior to commit 8520e224f547 ("bpf, cgroups:
Fix cgroup v2 fallback on v1/v2 mixed mode") we would just return, and later on in sock_cgroup_ptr(), we were NULL-testing the cgroup in fast-path, and iff indeed NULL returning the root cgroup (v ?: &cgrp_dfl_root.cgrp). Rather than re-adding the NULL-test to the fast-path we can just assign it once from cgroup_sk_alloc() given v1/v2 handling has been simplified. The migration from NULL test with returning &cgrp_dfl_root.cgrp to assigning &cgrp_dfl_root.cgrp directly does /not/ change behavior for callers of sock_cgroup_ptr().
syzkaller was able to trigger a splat in the legacy netrom code base, where the RX handler in nr_rx_frame() calls nr_make_new() which calls sk_alloc() and therefore cgroup_sk_alloc() with in_interrupt() condition. Thus the NULL skcd->cgroup, where it trips over on cgroup_sk_free() side given it expects a non-NULL object. There are a few other candidates aside from netrom which have similar pattern where in their accept-like implementation, they just call to sk_alloc() and thus cgroup_sk_alloc() instead of sk_clone_lock() with the corresponding cgroup_sk_clone() which then inherits the cgroup from the parent socket. None of them are related to core protocols where BPF cgroup programs are running from. However, in future, they should follow to implement a similar inheritance mechanism.
Additionally, with a !CONFIG_CGROUP_NET_PRIO and !CONFIG_CGROUP_NET_CLASSID configuration, the same issue was exposed also prior to 8520e224f547 due to commit e876ecc67db8 ("cgroup: memcg: net: do not associate sock with unrelated cgroup") which added the early in_interrupt() return back then.
--- kernel/cgroup/cgroup.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
kernel/cgroup/cgroup.c +12 -5
@@ -6559,22 +6559,29 @@ int cgroup_parse_float(const char *inputvoid cgroup_sk_alloc (struct sock_cgroup_data *skcd) { -/* Don't associate the sock with unrelated interrupted task's cgroup. */ -if (in_interrupt ()) -return ; +struct cgroup *cgroup;rcu_read_lock (); +/* Don't associate the sock with unrelated interrupted task's cgroup. */ +if (in_interrupt ()) { + cgroup = &cgrp_dfl_root.cgrp; +cgroup_get (cgroup); + goto out; + } +while (true) {struct css_set *cset; cset =task_css_set (current);if (likely (cgroup_tryget (cset->dfl_cgrp))) { - skcd->cgroup = cset->dfl_cgrp; -cgroup_bpf_get (cset->dfl_cgrp); + cgroup = cset->dfl_cgrp;break ; }cpu_relax (); } +out: + skcd->cgroup = cgroup; +cgroup_bpf_get (cgroup);rcu_read_unlock (); }
Greg Kroah-Hartman
maintainerPATCH 54/186 sch/netem: fix use after free in netem_dequeue
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Hemminger <[email protected]>
commit 3b3a2a9c6349e25a025d2330f479bc33a6ccb54a upstream.
If netem_dequeue() enqueues packet to inner qdisc and that qdisc returns __NET_XMIT_STOLEN. The packet is dropped but qdisc_tree_reduce_backlog() is not called to update the parent's q.qlen, leading to the similar use-after-free as Commit e04991a48dbaf382 ("netem: fix return value if duplicate enqueue fails")
Commands to trigger KASAN UaF:
ip link add type dummy
ip link set lo up
ip link set dummy0 up
tc qdisc add dev lo parent root handle 1: drr
tc filter add dev lo parent 1: basic classid 1:1
tc class add dev lo classid 1:1 drr
tc qdisc add dev lo parent 1:1 handle 2: netem
tc qdisc add dev lo parent 2: handle 3: drr
tc filter add dev lo parent 3: basic classid 3:1 action mirred egress redirect dev dummy0
tc class add dev lo classid 3:1 drr
ping -c1 -W0.01 localhost # Trigger bug
tc class del dev lo classid 1:1
tc class add dev lo classid 1:1 drr
ping -c1 -W0.01 localhost # UaF
--- net/sched/sch_netem.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
net/sched/sch_netem.c +4 -5
@@ -733,11 +733,10 @@ deliver: err =qdisc_enqueue (skb, q->qdisc, &to_free);kfree_skb_list (to_free); -if (err !=NET_XMIT_SUCCESS && -net_xmit_drop_count (err)) { -qdisc_qstats_drop (sch); -qdisc_tree_reduce_backlog (sch,1 , - pkt_len); +if (err !=NET_XMIT_SUCCESS ) { +if (net_xmit_drop_count (err)) +qdisc_qstats_drop (sch); +qdisc_tree_reduce_backlog (sch,1 , pkt_len); } goto tfifo_dequeue; }
Greg Kroah-Hartman
maintainerPATCH 55/186 ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: robelin <[email protected]>
commit b4a90b543d9f62d3ac34ec1ab97fc5334b048565 upstream.
When using kernel with the following extra config,
- CONFIG_KASAN=y
- CONFIG_KASAN_GENERIC=y
- CONFIG_KASAN_INLINE=y
- CONFIG_KASAN_VMALLOC=y
- CONFIG_FRAME_WARN=4096
kernel detects that snd_pcm_suspend_all() access a freed 'snd_soc_pcm_runtime' object when the system is suspended, which leads to a use-after-free bug:
[ 52.047746] BUG: KASAN: use-after-free in snd_pcm_suspend_all+0x1a8/0x270 [ 52.047765] Read of size 1 at addr ffff0000b9434d50 by task systemd-sleep/2330
[ 52.047785] Call trace: [ 52.047787] dump_backtrace+0x0/0x3c0 [ 52.047794] show_stack+0x34/0x50 [ 52.047797] dump_stack_lvl+0x68/0x8c [ 52.047802] print_address_description.constprop.0+0x74/0x2c0 [ 52.047809] kasan_report+0x210/0x230 [ 52.047815] __asan_report_load1_noabort+0x3c/0x50 [ 52.047820] snd_pcm_suspend_all+0x1a8/0x270 [ 52.047824] snd_soc_suspend+0x19c/0x4e0
The snd_pcm_sync_stop() has a NULL check on 'substream->runtime' before making any access. So we need to always set 'substream->runtime' to NULL everytime we kfree() it.
--- sound/soc/soc-dapm.c | 1 + 1 file changed, 1 insertion(+)
sound/soc/soc-dapm.c +1 -0
@@ -4014,6 +4014,7 @@ static int snd_soc_dai_link_event(structcase SND_SOC_DAPM_POST_PMD :kfree (substream->runtime); + substream->runtime =NULL ;break ;default :
Greg Kroah-Hartman
maintainerPATCH 56/186 ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius devices
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Sandberg <[email protected]>
commit 4178d78cd7a86510ba68d203f26fc01113c7f126 upstream.
The Sirius notebooks have two sets of speakers 0x17 (sides) and 0x1d (top center). The side speakers are active by default but the top speakers aren't.
This patch provides a pincfg quirk to activate the top speakers.
--- sound/pci/hda/patch_conexant.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
sound/pci/hda/patch_conexant.c +11 -0
@@ -238,6 +238,7 @@ enum {CXT_FIXUP_HEADSET_MIC ,CXT_FIXUP_HP_MIC_NO_PRESENCE ,CXT_PINCFG_SWS_JS201D , + CXT_PINCFG_TOP_SPEAKER, };/* for hda_fixup_thinkpad_acpi() */
@@ -905,6 +906,13 @@ static const struct hda_fixup cxt_fixups .type = HDA_FIXUP_PINS, .v.pins = cxt_pincfg_sws_js201d, }, + [CXT_PINCFG_TOP_SPEAKER] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl []) { + {0x1d ,0x82170111 }, + { } + }, + }, };static const struct snd_pci_quirk cxt5045_fixups[] = {
@@ -1001,6 +1009,8 @@ static const struct snd_pci_quirk cxt506SND_PCI_QUIRK_VENDOR (0x17aa ,"Thinkpad" ,CXT_FIXUP_THINKPAD_ACPI ),SND_PCI_QUIRK (0x1c06 ,0x2011 ,"Lemote A1004" ,CXT_PINCFG_LEMOTE_A1004 ),SND_PCI_QUIRK (0x1c06 ,0x2012 ,"Lemote A1205" ,CXT_PINCFG_LEMOTE_A1205 ), +SND_PCI_QUIRK (0x2782 ,0x12c3 ,"Sirius Gen1" ,CXT_PINCFG_TOP_SPEAKER ), + SND_PCI_QUIRK(0x2782, 0x12c5, "Sirius Gen2", CXT_PINCFG_TOP_SPEAKER), {} };
@@ -1020,6 +1030,7 @@ static const struct hda_model_fixup cxt5 { .id = CXT_FIXUP_HP_MIC_NO_PRESENCE, .name = "hp-mic-fix" }, { .id = CXT_PINCFG_LENOVO_NOTEBOOK, .name = "lenovo-20149" }, { .id = CXT_PINCFG_SWS_JS201D, .name = "sws-js201d" }, + { .id = CXT_PINCFG_TOP_SPEAKER, .name = "sirius-top-speaker" }, {} };
Greg Kroah-Hartman
maintainerPATCH 57/186 ALSA: hda/realtek: add patch for internal mic in Lenovo V145
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Terry Cheong <[email protected]>
commit ef27e89e7f3015be2b3c124833fbd6d2e4686561 upstream.
Lenovo V145 is having phase inverted dmic but simply applying inverted dmic fixups does not work. Chaining up verb fixes for ALC283 enables inverting dmic fixup to work properly.
--- sound/pci/hda/patch_realtek.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/pci/hda/patch_realtek.c +9 -0
@@ -6968,6 +6968,7 @@ enum {ALC236_FIXUP_HP_GPIO_LED ,ALC236_FIXUP_HP_MUTE_LED ,ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF , +ALC236_FIXUP_LENOVO_INV_DMIC ,ALC298_FIXUP_SAMSUNG_AMP ,ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET , ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET,
@@ -8361,6 +8362,12 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_mute_led_micmute_vref, }, + [ALC236_FIXUP_LENOVO_INV_DMIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_inv_dmic, + .chained = true, + .chain_id = ALC283_FIXUP_INT_MIC, + }, [ALC298_FIXUP_SAMSUNG_AMP] = { .type = HDA_FIXUP_FUNC, .v.func = alc298_fixup_samsung_amp,
@@ -9355,6 +9362,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x17aa ,0x3852 ,"Lenovo Yoga 7 14ITL5" ,ALC287_FIXUP_YOGA7_14ITL_SPEAKERS ),SND_PCI_QUIRK (0x17aa ,0x3853 ,"Lenovo Yoga 7 15ITL5" ,ALC287_FIXUP_YOGA7_14ITL_SPEAKERS ),SND_PCI_QUIRK (0x17aa ,0x3902 ,"Lenovo E50-80" ,ALC269_FIXUP_DMIC_THINKPAD_ACPI ), +SND_PCI_QUIRK (0x17aa ,0x3913 ,"Lenovo 145" ,ALC236_FIXUP_LENOVO_INV_DMIC ),SND_PCI_QUIRK (0x17aa ,0x3977 ,"IdeaPad S210" ,ALC283_FIXUP_INT_MIC ),SND_PCI_QUIRK (0x17aa ,0x3978 ,"Lenovo B50-70" ,ALC269_FIXUP_DMIC_THINKPAD_ACPI ), SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
@@ -9596,6 +9604,7 @@ static const struct hda_model_fixup alc2 {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, {.id = ALC285_FIXUP_HP_GPIO_AMP_INIT, .name = "alc285-hp-amp-init"}, + {.id = ALC236_FIXUP_LENOVO_INV_DMIC, .name = "alc236-fixup-lenovo-inv-mic"}, {} };#define ALC225_STANDARD_PINS \
Greg Kroah-Hartman
maintainerPATCH 58/186 ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilien Perreault <[email protected]>
commit 47a9e8dbb8d4713a9aac7cc6ce3c82dcc94217d8 upstream.
The mute LED on this HP laptop uses ALC236 and requires a quirk to function. This patch enables the existing quirk for the device.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -9112,6 +9112,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x103c ,0x87f5 ,"HP" ,ALC287_FIXUP_HP_GPIO_LED ),SND_PCI_QUIRK (0x103c ,0x87f6 ,"HP Spectre x360 14" ,ALC245_FIXUP_HP_X360_AMP ),SND_PCI_QUIRK (0x103c ,0x87f7 ,"HP Spectre x360 14" ,ALC245_FIXUP_HP_X360_AMP ), +SND_PCI_QUIRK (0x103c ,0x87fd ,"HP Laptop 14-dq2xxx" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x87fe ,"HP Laptop 15s-fq2xxx" ,ALC236_FIXUP_HP_MUTE_LED_COEFBIT2 ),SND_PCI_QUIRK (0x103c ,0x8805 ,"HP ProBook 650 G8 Notebook PC" ,ALC236_FIXUP_HP_GPIO_LED ), SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 59/186 ata: libata: Fix memory leak for error path in ata_host_alloc()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
commit 284b75a3d83c7631586d98f6dede1d90f128f0db upstream.
In ata_host_alloc(), if devres_alloc() fails to allocate the device host resource data pointer, the already allocated ata_host structure is not freed before returning from the function. This results in a potential memory leak.
Call kfree(host) before jumping to the error handling path to ensure that the ata_host structure is properly freed if devres_alloc() fails.
--- drivers/ata/libata-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/ata/libata-core.c +3 -1
@@ -5429,8 +5429,10 @@ struct ata_host *ata_host_alloc(struct d } dr =devres_alloc (ata_devres_release,0 ,GFP_KERNEL ); -if (!dr) +if (!dr) { +kfree (host); goto err_out; + }devres_add (dev, dr);dev_set_drvdata (dev, host);
Greg Kroah-Hartman
maintainerPATCH 60/186 irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <[email protected]>
commit c5af2c90ba5629f0424a8d315f75fb8d91713c3c upstream.
gicv2m_of_init() fails to perform an of_node_put() when of_address_to_resource() fails, leading to a refcount leak.
Address this by moving the error handling path outside of the loop and making it common to all failure modes.
--- drivers/irqchip/irq-gic-v2m.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/irqchip/irq-gic-v2m.c +3 -3
@@ -442,12 +442,12 @@ static int __init gicv2m_of_init(struct ret =gicv2m_init_one (&child->fwnode, spi_start, nr_spis, &res,0 ); -if (ret) { -of_node_put (child); +if (ret)break ; - } } +if (ret && child) +of_node_put (child);if (!ret) ret =gicv2m_allocate_domains (parent);if (ret)
Greg Kroah-Hartman
maintainerPATCH 61/186 Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
commit 532f8bcd1c2c4e8112f62e1922fd1703bc0ffce0 upstream.
This reverts commit 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 which breaks compatibility with commands like:
bluetoothd[46328]: @ MGMT Command: Load.. (0x0013) plen 74 {0x0001} [hci0]
Keys: 2
BR/EDR Address: C0:DC:DA:A5:E5:47 (Samsung Electronics Co.,Ltd)
Key type: Authenticated key from P-256 (0x03)
Central: 0x00
Encryption size: 16
Diversifier[2]: 0000
Randomizer[8]: 0000000000000000
Key[16]: 6ed96089bd9765be2f2c971b0b95f624
LE Address: D7:2A:DE:1E:73:A2 (Static)
Key type: Unauthenticated key from P-256 (0x02)
Central: 0x00
Encryption size: 16
Diversifier[2]: 0000
Randomizer[8]: 0000000000000000
Key[16]: 87dd2546ededda380ffcdc0a8faa4597
@ MGMT Event: Command Status (0x0002) plen 3 {0x0001} [hci0]
Load Long Term Keys (0x0013)
Status: Invalid Parameters (0x0d)--- include/net/bluetooth/hci_core.h | 5 ----- net/bluetooth/mgmt.c | 25 +++++++------------------ net/bluetooth/smp.c | 7 ------- 3 files changed, 7 insertions(+), 30 deletions(-)
include/net/bluetooth/hci_core.h +0 -5
@@ -174,7 +174,6 @@ struct blocked_key {struct smp_csrk {bdaddr_t bdaddr;u8 bdaddr_type; -u8 link_type;u8 type;u8 val[16 ]; };
@@ -184,7 +183,6 @@ struct smp_ltk {struct rcu_head rcu;bdaddr_t bdaddr;u8 bdaddr_type; -u8 link_type;u8 authenticated;u8 type;u8 enc_size;
@@ -199,7 +197,6 @@ struct smp_irk {bdaddr_t rpa;bdaddr_t bdaddr;u8 addr_type; -u8 link_type;u8 val[16 ]; };
@@ -207,8 +204,6 @@ struct link_key {struct list_head list;struct rcu_head rcu;bdaddr_t bdaddr; -u8 bdaddr_type; -u8 link_type;u8 type;u8 val[HCI_LINK_KEY_SIZE ];u8 pin_len;
net/bluetooth/mgmt.c +7 -18
@@ -2373,8 +2373,7 @@ static int load_link_keys(struct sock *sfor (i =0 ; i < key_count; i++) {struct mgmt_link_key_info *key = &cp->keys[i]; -/* Considering SMP over BREDR/LE, there is no need to check addr_type */ -if (key->type >0x08 ) +if (key->addr.type !=BDADDR_BREDR || key->type >0x08 )return mgmt_cmd_status (sk, hdev->id,MGMT_OP_LOAD_LINK_KEYS ,MGMT_STATUS_INVALID_PARAMS );
@@ -5919,7 +5918,6 @@ static int load_irks(struct sock *sk, stfor (i =0 ; i < irk_count; i++) {struct mgmt_irk_info *irk = &cp->irks[i]; -u8 addr_type =le_addr_type (irk->addr.type); if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_IRK,
@@ -5929,12 +5927,8 @@ static int load_irks(struct sock *sk, stcontinue ; } -/* When using SMP over BR/EDR, the addr type should be set to BREDR */ -if (irk->addr.type ==BDADDR_BREDR ) - addr_type =BDADDR_BREDR ; -hci_add_irk (hdev, &irk->addr.bdaddr, - addr_type, irk->val, +le_addr_type (irk->addr.type), irk->val,BDADDR_ANY ); }
@@ -6015,7 +6009,6 @@ static int load_long_term_keys(struct sofor (i =0 ; i < key_count; i++) {struct mgmt_ltk_info *key = &cp->keys[i];u8 type, authenticated; -u8 addr_type =le_addr_type (key->addr.type); if (hci_is_blocked_key(hdev, HCI_BLOCKED_KEY_TYPE_LTK,
@@ -6050,12 +6043,8 @@ static int load_long_term_keys(struct socontinue ; } -/* When using SMP over BR/EDR, the addr type should be set to BREDR */ -if (key->addr.type ==BDADDR_BREDR ) - addr_type =BDADDR_BREDR ; -hci_add_ltk (hdev, &key->addr.bdaddr, - addr_type, type, authenticated, +le_addr_type (key->addr.type), type, authenticated, key->val, key->enc_size, key->ediv, key->rand); }
@@ -8058,7 +8047,7 @@ void mgmt_new_link_key(struct hci_dev *h ev.store_hint = persistent;bacpy (&ev.key.addr.bdaddr, &key->bdaddr); - ev.key.addr.type =link_to_bdaddr (key->link_type, key->bdaddr_type); + ev.key.addr.type =BDADDR_BREDR ; ev.key.type = key->type;memcpy (ev.key.val, key->val,HCI_LINK_KEY_SIZE ); ev.key.pin_len = key->pin_len;
@@ -8109,7 +8098,7 @@ void mgmt_new_ltk(struct hci_dev *hdev, ev.store_hint = persistent;bacpy (&ev.key.addr.bdaddr, &key->bdaddr); - ev.key.addr.type =link_to_bdaddr (key->link_type, key->bdaddr_type); + ev.key.addr.type =link_to_bdaddr (LE_LINK , key->bdaddr_type); ev.key.type =mgmt_ltk_type (key); ev.key.enc_size = key->enc_size; ev.key.ediv = key->ediv;
@@ -8138,7 +8127,7 @@ void mgmt_new_irk(struct hci_dev *hdev,bacpy (&ev.rpa, &irk->rpa);bacpy (&ev.irk.addr.bdaddr, &irk->bdaddr); - ev.irk.addr.type =link_to_bdaddr (irk->link_type, irk->addr_type); + ev.irk.addr.type =link_to_bdaddr (LE_LINK , irk->addr_type);memcpy (ev.irk.val, irk->val,sizeof (irk->val));mgmt_event (MGMT_EV_NEW_IRK , hdev, &ev,sizeof (ev),NULL );
@@ -8167,7 +8156,7 @@ void mgmt_new_csrk(struct hci_dev *hdev, ev.store_hint = persistent;bacpy (&ev.key.addr.bdaddr, &csrk->bdaddr); - ev.key.addr.type =link_to_bdaddr (csrk->link_type, csrk->bdaddr_type); + ev.key.addr.type =link_to_bdaddr (LE_LINK , csrk->bdaddr_type); ev.key.type = csrk->type;memcpy (ev.key.val, csrk->val,sizeof (csrk->val));
net/bluetooth/smp.c +0 -7
@@ -1060,7 +1060,6 @@ static void smp_notify_keys(struct l2cap }if (smp->remote_irk) { - smp->remote_irk->link_type = hcon->type;mgmt_new_irk (hdev, smp->remote_irk, persistent);/* Now that user space can be considered to know the
@@ -1075,28 +1074,24 @@ static void smp_notify_keys(struct l2cap }if (smp->csrk) { - smp->csrk->link_type = hcon->type; smp->csrk->bdaddr_type = hcon->dst_type;bacpy (&smp->csrk->bdaddr, &hcon->dst);mgmt_new_csrk (hdev, smp->csrk, persistent); }if (smp->responder_csrk) { - smp->responder_csrk->link_type = hcon->type; smp->responder_csrk->bdaddr_type = hcon->dst_type;bacpy (&smp->responder_csrk->bdaddr, &hcon->dst);mgmt_new_csrk (hdev, smp->responder_csrk, persistent); }if (smp->ltk) { - smp->ltk->link_type = hcon->type; smp->ltk->bdaddr_type = hcon->dst_type;bacpy (&smp->ltk->bdaddr, &hcon->dst);mgmt_new_ltk (hdev, smp->ltk, persistent); }if (smp->responder_ltk) { - smp->responder_ltk->link_type = hcon->type; smp->responder_ltk->bdaddr_type = hcon->dst_type;bacpy (&smp->responder_ltk->bdaddr, &hcon->dst);mgmt_new_ltk (hdev, smp->responder_ltk, persistent);
@@ -1116,8 +1111,6 @@ static void smp_notify_keys(struct l2cap key =hci_add_link_key (hdev, smp->conn->hcon, &hcon->dst, smp->link_key, type,0 , &persistent);if (key) { - key->link_type = hcon->type; - key->bdaddr_type = hcon->dst_type;mgmt_new_link_key (hdev, key, persistent);/* Don't keep debug keys around if the relevant
Greg Kroah-Hartman
maintainerPATCH 62/186 Bluetooth: MGMT: Ignore keys being loaded with invalid type
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
commit 1e9683c9b6ca88cc9340cdca85edd6134c8cffe3 upstream.
Due to 59b047bc98084f8af2c41483e4d68a5adf2fa7f7 there could be keys stored with the wrong address type so this attempt to detect it and ignore them instead of just failing to load all keys.
--- net/bluetooth/mgmt.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)
net/bluetooth/mgmt.c +19 -18
@@ -2370,15 +2370,6 @@ static int load_link_keys(struct sock *sbt_dev_dbg (hdev,"debug_keys %u key_count %u" , cp->debug_keys, key_count); -for (i =0 ; i < key_count; i++) { -struct mgmt_link_key_info *key = &cp->keys[i]; - -if (key->addr.type !=BDADDR_BREDR || key->type >0x08 ) -return mgmt_cmd_status (sk, hdev->id, -MGMT_OP_LOAD_LINK_KEYS , -MGMT_STATUS_INVALID_PARAMS ); - } -hci_dev_lock (hdev);hci_link_keys_clear (hdev);
@@ -2403,6 +2394,19 @@ static int load_link_keys(struct sock *scontinue ; } +if (key->addr.type !=BDADDR_BREDR ) { +bt_dev_warn (hdev, +"Invalid link address type %u for %pMR" , + key->addr.type, &key->addr.bdaddr); +continue ; + } + +if (key->type >0x08 ) { +bt_dev_warn (hdev,"Invalid link key type %u for %pMR" , + key->type, &key->addr.bdaddr); +continue ; + } +/* Always ignore debug keys and require a new pairing if * the user wants to use them. */
@@ -5993,15 +5997,6 @@ static int load_long_term_keys(struct sobt_dev_dbg (hdev,"key_count %u" , key_count); -for (i =0 ; i < key_count; i++) { -struct mgmt_ltk_info *key = &cp->keys[i]; - -if (!ltk_is_valid (key)) -return mgmt_cmd_status (sk, hdev->id, -MGMT_OP_LOAD_LONG_TERM_KEYS , -MGMT_STATUS_INVALID_PARAMS ); - } -hci_dev_lock (hdev);hci_smp_ltks_clear (hdev);
@@ -6017,6 +6012,12 @@ static int load_long_term_keys(struct so &key->addr.bdaddr);continue ; } + +if (!ltk_is_valid (key)) { +bt_dev_warn (hdev,"Invalid LTK for %pMR" , + &key->addr.bdaddr); +continue ; + }switch (key->type) {case MGMT_LTK_UNAUTHENTICATED :
Greg Kroah-Hartman
maintainerPATCH 63/186 mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sam Protsenko <[email protected]>
commit 8396c793ffdf28bb8aee7cfe0891080f8cab7890 upstream.
Commit 616f87661792 ("mmc: pass queue_limits to blk_mq_alloc_disk") [1] revealed the long living issue in dw_mmc.c driver, existing since the time when it was first introduced in commit f95f3850f7a9 ("mmc: dw_mmc:
Add Synopsys DesignWare mmc host driver."), also making kernel boot broken on platforms using dw_mmc driver with 16K or 64K pages enabled, with this message in dmesg:
mmcblk: probe of mmc0:0001 failed with error -22
That's happening because mmc_blk_probe() fails when it calls blk_validate_limits() consequently, which returns the error due to failed max_segment_size check in this code:
/*
* The maximum segment size has an odd historic 64k default that
* drivers probably should override. Just like the I/O size we
* require drivers to at least handle a full page per segment.
*/
...
if (WARN_ON_ONCE(lim->max_segment_size < PAGE_SIZE))
return -EINVAL;In case when IDMAC (Internal DMA Controller) is used, dw_mmc.c always sets .max_seg_size to 4 KiB:
mmc->max_seg_size = 0x1000;
The comment in the code above explains why it's incorrect. Arnd suggested setting .max_seg_size to .max_req_size to fix it, which is also what some other drivers are doing:
$ grep -rl 'max_seg_size.*=.*max_req_size' drivers/mmc/host/ | \
wc -l
18This change is not only fixing the boot with 16K/64K pages, but also leads to a better MMC performance. The linear write performance was tested on E850-96 board (eMMC only), before commit [1] (where it's possible to boot with 16K/64K pages without this fix, to be able to do a comparison). It was tested with this command:
# dd if=/dev/zero of=somefile bs=1M count=500 oflag=sync
Test results are as follows:
- 4K pages, .max_seg_size = 4 KiB: 94.2 MB/s
- 4K pages, .max_seg_size = .max_req_size = 512 KiB: 96.9 MB/s
- 16K pages, .max_seg_size = 4 KiB: 126 MB/s - 16K pages, .max_seg_size = .max_req_size = 2 MiB: 128 MB/s - 64K pages, .max_seg_size = 4 KiB: 138 MB/s - 64K pages, .max_seg_size = .max_req_size = 8 MiB: 138 MB/s
Unfortunately, SD card controller is not enabled in E850-96 yet, so it wasn't possible for me to run the test on some cheap SD cards to check this patch's impact on those. But it's possible that this change might also reduce the writes count, thus improving SD/eMMC longevity.
All credit for the analysis and the suggested solution goes to Arnd.
[1] https://lore.kernel.org/all/[email protected]/
--- drivers/mmc/host/dw_mmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/dw_mmc.c +2 -2
@@ -2826,8 +2826,8 @@ static int dw_mci_init_slot(struct dw_mcif (host->use_dma ==TRANS_MODE_IDMAC ) { mmc->max_segs = host->ring_size; mmc->max_blk_size =65535 ; - mmc->max_seg_size =0x1000 ; - mmc->max_req_size = mmc->max_seg_size * host->ring_size; + mmc->max_req_size =DW_MCI_DESC_DATA_LENGTH * host->ring_size; + mmc->max_seg_size = mmc->max_req_size; mmc->max_blk_count = mmc->max_req_size /512 ; }else if (host->use_dma ==TRANS_MODE_EDMAC ) { mmc->max_segs =64 ;
Greg Kroah-Hartman
maintainerPATCH 64/186 mmc: sdhci-of-aspeed: fix module autoloading
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liao Chen <[email protected]>
commit 6e540da4c1db7b840e347c4dfe48359b18b7e376 upstream.
Add MODULE_DEVICE_TABLE(), so modules could be properly autoloaded based on the alias from of_device_id table.
--- drivers/mmc/host/sdhci-of-aspeed.c | 1 + 1 file changed, 1 insertion(+)
drivers/mmc/host/sdhci-of-aspeed.c +1 -0
@@ -236,6 +236,7 @@ static const struct of_device_id aspeed_ { .compatible = "aspeed,ast2600-sdhci", }, { } }; +MODULE_DEVICE_TABLE (of, aspeed_sdhci_of_match);static struct platform_driver aspeed_sdhci_driver = { .driver = {
Greg Kroah-Hartman
maintainerPATCH 65/186 fuse: update stats for pages in dropped aux writeback list
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joanne Koong <[email protected]>
commit f7790d67785302b3116bbbfda62a5a44524601a3 upstream.
In the case where the aux writeback list is dropped (e.g. the pages have been truncated or the connection is broken), the stats for its pages and backing device info need to be updated as well.
--- fs/fuse/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/fuse/file.c +7 -1
@@ -1692,10 +1692,16 @@ __acquires(fi->lock)fuse_writepage_finish (fm, wpa);spin_unlock (&fi->lock); -/* After fuse_writepage_finish() aux request list is private */ +/* After rb_erase() aux request list is private */ for (aux = wpa->next; aux; aux = next) { +struct backing_dev_info *bdi =inode_to_bdi (aux->inode); + next = aux->next; aux->next =NULL ; + +dec_wb_stat (&bdi->wb,WB_WRITEBACK ); +dec_node_page_state (aux->ia.ap.pages[0 ],NR_WRITEBACK_TEMP ); +wb_writeout_inc (&bdi->wb);fuse_writepage_free (aux); }
Greg Kroah-Hartman
maintainerPATCH 66/186 fuse: use unsigned type for getxattr/listxattr size truncation
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit b18915248a15eae7d901262f108d6ff0ffb4ffc1 upstream.
The existing code uses min_t(ssize_t, outarg.size, XATTR_LIST_MAX) when parsing the FUSE daemon's response to a zero-length getxattr/listxattr request.
On 32-bit kernels, where ssize_t and outarg.size are the same size, this is
wrong: The min_t() will pass through any size values that are negative when interpreted as signed.fuse_listxattr() will then return this userspace-supplied negative value, which callers will treat as an error value.
This kind of bug pattern can lead to fairly bad security bugs because of how error codes are used in the Linux kernel. If a caller were to convert the numeric error into an error pointer, like so:
struct foo *func(...) {
int len = fuse_getxattr(..., NULL, 0);
if (len < 0)
return ERR_PTR(len);
...
}then it would end up returning this userspace-supplied negative value cast to a pointer - but the caller of this function wouldn't recognize it as an error pointer (IS_ERR_VALUE() only detects values in the narrow range in which legitimate errno values are), and so it would just be treated as a kernel pointer.
I think there is at least one theoretical codepath where this could happen, but that path would involve virtio-fs with submounts plus some weird SELinux configuration, so I think it's probably not a concern in practice.
--- fs/fuse/xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/fuse/xattr.c +2 -2
@@ -79,7 +79,7 @@ ssize_t fuse_getxattr(struct inode *inod } ret =fuse_simple_request (fm, &args);if (!ret && !size) - ret =min_t (ssize_t, outarg.size,XATTR_SIZE_MAX ); + ret =min_t (size_t, outarg.size,XATTR_SIZE_MAX );if (ret == -ENOSYS ) { fm->fc->no_getxattr =1 ; ret = -EOPNOTSUPP ;
@@ -141,7 +141,7 @@ ssize_t fuse_listxattr(struct dentry *en } ret =fuse_simple_request (fm, &args);if (!ret && !size) - ret =min_t (ssize_t, outarg.size,XATTR_LIST_MAX ); + ret =min_t (size_t, outarg.size,XATTR_LIST_MAX );if (ret >0 && size) ret =fuse_verify_xattr_list (list, ret);if (ret == -ENOSYS ) {
Greg Kroah-Hartman
maintainerPATCH 67/186 clk: qcom: clk-alpha-pll: Fix the pll post div mask
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit 2c4553e6c485a96b5d86989eb9654bf20e51e6dd upstream.
The PLL_POST_DIV_MASK should be 0 to (width - 1) bits. Fix it.
--- drivers/clk/qcom/clk-alpha-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/clk-alpha-pll.c +1 -1
@@ -38,7 +38,7 @@#define PLL_USER_CTL (p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL])# define PLL_POST_DIV_SHIFT 8 -# define PLL_POST_DIV_MASK (p) GENMASK((p)->width, 0) +# define PLL_POST_DIV_MASK (p) GENMASK((p)->width - 1, 0)# define PLL_ALPHA_EN BIT(24)# define PLL_ALPHA_MODE BIT(25)# define PLL_VCO_SHIFT 20
Greg Kroah-Hartman
maintainerPATCH 68/186 clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satya Priya Kakitapalli <[email protected]>
commit 4ad1ed6ef27cab94888bb3c740c14042d5c0dff2 upstream.
Correct the pll postdiv shift used in clk_trion_pll_postdiv_set_rate API. The shift value is not same for different types of plls and should be taken from the pll's .post_div_shift member.
--- drivers/clk/qcom/clk-alpha-pll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/clk/qcom/clk-alpha-pll.c +2 -2
@@ -1321,8 +1321,8 @@ clk_trion_pll_postdiv_set_rate(struct cl }return regmap_update_bits (regmap,PLL_USER_CTL (pll), -PLL_POST_DIV_MASK (pll) <<PLL_POST_DIV_SHIFT , - val <<PLL_POST_DIV_SHIFT ); +PLL_POST_DIV_MASK (pll) << pll->post_div_shift, + val << pll->post_div_shift); }const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
Greg Kroah-Hartman
maintainerPATCH 69/186 can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Arlott <[email protected]>
commit 7dd9c26bd6cf679bcfdef01a8659791aa6487a29 upstream.
The mcp251x_hw_wake() function is called with the mpc_lock mutex held and disables the interrupt handler so that no interrupts can be processed while waking the device. If an interrupt has already occurred then waiting for the interrupt handler to complete will deadlock because it will be trying to acquire the same mutex.
CPU0 CPU1
---- ----mcp251x_open()
mutex_lock(&priv->mcp_lock)
request_threaded_irq()
<interrupt>
mcp251x_can_ist()
mutex_lock(&priv->mcp_lock) mcp251x_hw_wake()
disable_irq() <-- deadlock
Use disable_irq_nosync() instead because the interrupt handler does everything while holding the mutex so it doesn't matter if it's still running.
--- drivers/net/can/spi/mcp251x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/spi/mcp251x.c +1 -1
@@ -755,7 +755,7 @@ static int mcp251x_hw_wake(struct spi_deint ret;/* Force wakeup interrupt to wake device, but don't execute IST */ -disable_irq (spi->irq); +disable_irq_nosync (spi->irq);mcp251x_write_2regs (spi,CANINTE ,CANINTE_WAKIE ,CANINTF_WAKIF );/* Wait for oscillator startup timer after wake up */
Greg Kroah-Hartman
maintainerPATCH 70/186 tracing: Avoid possible softlockup in tracing_iter_reset()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Yejian <[email protected]>
commit 49aa8a1f4d6800721c7971ed383078257f12e8f9 upstream.
In __tracing_open(), when max latency tracers took place on the cpu, the time start of its buffer would be updated, then event entries with timestamps being earlier than start of the buffer would be skipped (see tracing_iter_reset()).
Softlockup will occur if the kernel is non-preemptible and too many entries were skipped in the loop that reset every cpu buffer, so add cond_resched() to avoid it.
--- kernel/trace/trace.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/trace/trace.c +2 -0
@@ -3742,6 +3742,8 @@ void tracing_iter_reset(struct trace_itebreak ; entries++;ring_buffer_iter_advance (buf_iter); +/* This could be a big loop */ +cond_resched (); }per_cpu_ptr (iter->array_buffer->data, cpu)->skipped_entries = entries;
Greg Kroah-Hartman
maintainerPATCH 71/186 ila: call nf_unregister_net_hooks() sooner
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
commit 031ae72825cef43e4650140b800ad58bf7a6a466 upstream.
syzbot found an use-after-free Read in ila_nf_input [1]
Issue here is that ila_xlat_exit_net() frees the rhashtable, then call nf_unregister_net_hooks().
It should be done in the reverse way, with a synchronize_rcu().
This is a good match for a pre_exit() method.
[1]
BUG: KASAN: use-after-free in rht_key_hashfn include/linux/rhashtable.h:159 [inline]
BUG: KASAN: use-after-free in __rhashtable_lookup include/linux/rhashtable.h:604 [inline]
BUG: KASAN: use-after-free in rhashtable_lookup include/linux/rhashtable.h:646 [inline]
BUG: KASAN: use-after-free in rhashtable_lookup_fast+0x77a/0x9b0 include/linux/rhashtable.h:672
Read of size 4 at addr ffff888064620008 by task ksoftirqd/0/16
CPU: 0 UID: 0 PID: 16 Comm: ksoftirqd/0 Not tainted 6.11.0-rc4-syzkaller-00238-g2ad6d23f465a #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 08/06/2024
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:93 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119
print_address_description mm/kasan/report.c:377 [inline]
print_report+0x169/0x550 mm/kasan/report.c:488
kasan_report+0x143/0x180 mm/kasan/report.c:601
rht_key_hashfn include/linux/rhashtable.h:159 [inline]
__rhashtable_lookup include/linux/rhashtable.h:604 [inline]
rhashtable_lookup include/linux/rhashtable.h:646 [inline]
rhashtable_lookup_fast+0x77a/0x9b0 include/linux/rhashtable.h:672
ila_lookup_wildcards net/ipv6/ila/ila_xlat.c:132 [inline]
ila_xlat_addr net/ipv6/ila/ila_xlat.c:652 [inline]
ila_nf_input+0x1fe/0x3c0 net/ipv6/ila/ila_xlat.c:190
nf_hook_entry_hookfn include/linux/netfilter.h:154 [inline]
nf_hook_slow+0xc3/0x220 net/netfilter/core.c:626
nf_hook include/linux/netfilter.h:269 [inline]
NF_HOOK+0x29e/0x450 include/linux/netfilter.h:312
__netif_receive_skb_one_core net/core/dev.c:5661 [inline]
__netif_receive_skb+0x1ea/0x650 net/core/dev.c:5775
process_backlog+0x662/0x15b0 net/core/dev.c:6108
__napi_poll+0xcb/0x490 net/core/dev.c:6772
napi_poll net/core/dev.c:6841 [inline]
net_rx_action+0x89b/0x1240 net/core/dev.c:6963
handle_softirqs+0x2c4/0x970 kernel/softirq.c:554
run_ksoftirqd+0xca/0x130 kernel/softirq.c:928
smpboot_thread_fn+0x544/0xa30 kernel/smpboot.c:164
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x64620
flags: 0xfff00000000000(node=0|zone=1|lastcpupid=0x7ff)
page_type: 0xbfffffff(buddy)
raw: 00fff00000000000 ffffea0000959608 ffffea00019d9408 0000000000000000
raw: 0000000000000000 0000000000000003 00000000bfffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as freed
page last allocated via order 3, migratetype Unmovable, gfp_mask 0x52dc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_ZERO), pid 5242, tgid 5242 (syz-executor), ts 73611328570, free_ts 618981657187
set_page_owner include/linux/page_owner.h:32 [inline]
post_alloc_hook+0x1f3/0x230 mm/page_alloc.c:1493
prep_new_page mm/page_alloc.c:1501 [inline]
get_page_from_freelist+0x2e4c/0x2f10 mm/page_alloc.c:3439
__alloc_pages_noprof+0x256/0x6c0 mm/page_alloc.c:4695
__alloc_pages_node_noprof include/linux/gfp.h:269 [inline]
alloc_pages_node_noprof include/linux/gfp.h:296 [inline]
___kmalloc_large_node+0x8b/0x1d0 mm/slub.c:4103
__kmalloc_large_node_noprof+0x1a/0x80 mm/slub.c:4130
__do_kmalloc_node mm/slub.c:4146 [inline]
__kmalloc_node_noprof+0x2d2/0x440 mm/slub.c:4164
__kvmalloc_node_noprof+0x72/0x190 mm/util.c:650
bucket_table_alloc lib/rhashtable.c:186 [inline]
rhashtable_init_noprof+0x534/0xa60 lib/rhashtable.c:1071
ila_xlat_init_net+0xa0/0x110 net/ipv6/ila/ila_xlat.c:613
ops_init+0x359/0x610 net/core/net_namespace.c:139
setup_net+0x515/0xca0 net/core/net_namespace.c:343
copy_net_ns+0x4e2/0x7b0 net/core/net_namespace.c:508
create_new_namespaces+0x425/0x7b0 kernel/nsproxy.c:110
unshare_nsproxy_namespaces+0x124/0x180 kernel/nsproxy.c:228
ksys_unshare+0x619/0xc10 kernel/fork.c:3328
__do_sys_unshare kernel/fork.c:3399 [inline]
__se_sys_unshare kernel/fork.c:3397 [inline]
__x64_sys_unshare+0x38/0x40 kernel/fork.c:3397
page last free pid 11846 tgid 11846 stack trace:
reset_page_owner include/linux/page_owner.h:25 [inline]
free_pages_prepare mm/page_alloc.c:1094 [inline]
free_unref_page+0xd22/0xea0 mm/page_alloc.c:2612
__folio_put+0x2c8/0x440 mm/swap.c:128
folio_put include/linux/mm.h:1486 [inline]
free_large_kmalloc+0x105/0x1c0 mm/slub.c:4565
kfree+0x1c4/0x360 mm/slub.c:4588
rhashtable_free_and_destroy+0x7c6/0x920 lib/rhashtable.c:1169
ila_xlat_exit_net+0x55/0x110 net/ipv6/ila/ila_xlat.c:626
ops_exit_list net/core/net_namespace.c:173 [inline]
cleanup_net+0x802/0xcc0 net/core/net_namespace.c:640
process_one_work kernel/workqueue.c:3231 [inline]
process_scheduled_works+0xa2c/0x1830 kernel/workqueue.c:3312
worker_thread+0x86d/0xd40 kernel/workqueue.c:3390
kthread+0x2f0/0x390 kernel/kthread.c:389
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
Memory state around the buggy address:
ffff88806461ff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88806461ff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff888064620000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^
ffff888064620080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff888064620100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff--- net/ipv6/ila/ila.h | 1 + net/ipv6/ila/ila_main.c | 6 ++++++ net/ipv6/ila/ila_xlat.c | 13 +++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-)
net/ipv6/ila/ila.h +1 -0
@@ -108,6 +108,7 @@ int ila_lwt_init(void);void ila_lwt_fini (void );int ila_xlat_init_net (struct net *net); +void ila_xlat_pre_exit_net (struct net *net);void ila_xlat_exit_net (struct net *net);int ila_xlat_nl_cmd_add_mapping (struct sk_buff *skb,struct genl_info *info);
net/ipv6/ila/ila_main.c +6 -0
@@ -71,6 +71,11 @@ ila_xlat_init_fail:return err; } +static __net_exit void ila_pre_exit_net(struct net *net) +{ +ila_xlat_pre_exit_net (net); +} + static __net_exit void ila_exit_net(struct net *net) {ila_xlat_exit_net (net);
@@ -78,6 +83,7 @@ static __net_exit void ila_exit_net(strustatic struct pernet_operations ila_net_ops = { .init = ila_init_net, + .pre_exit = ila_pre_exit_net, .exit = ila_exit_net, .id = &ila_net_id, .size =sizeof (struct ila_net ),
net/ipv6/ila/ila_xlat.c +9 -4
@@ -616,6 +616,15 @@ int ila_xlat_init_net(struct net *net)return 0 ; } +void ila_xlat_pre_exit_net (struct net *net) +{ +struct ila_net *ilan =net_generic (net, ila_net_id); + +if (ilan->xlat.hooks_registered) +nf_unregister_net_hooks (net, ila_nf_hook_ops, +ARRAY_SIZE (ila_nf_hook_ops)); +} +void ila_xlat_exit_net (struct net *net) {struct ila_net *ilan =net_generic (net, ila_net_id);
@@ -623,10 +632,6 @@ void ila_xlat_exit_net(struct net *net)rhashtable_free_and_destroy (&ilan->xlat.rhash_table, ila_free_cb,NULL );free_bucket_spinlocks (ilan->xlat.locks); - -if (ilan->xlat.hooks_registered) -nf_unregister_net_hooks (net, ila_nf_hook_ops, -ARRAY_SIZE (ila_nf_hook_ops)); }static int ila_xlat_addr (struct sk_buff *skb,bool sir2ila)
Greg Kroah-Hartman
maintainerPATCH 72/186 sched: sch_cake: fix bulk flow accounting logic for host fairness
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toke Høiland-Jørgensen <[email protected]>
commit 546ea84d07e3e324644025e2aae2d12ea4c5896e upstream.
In sch_cake, we keep track of the count of active bulk flows per host, when running in dst/src host fairness mode, which is used as the round-robin weight when iterating through flows. The count of active bulk flows is updated whenever a flow changes state.
This has a peculiar interaction with the hash collision handling: when a hash collision occurs (after the set-associative hashing), the state of the hash bucket is simply updated to match the new packet that collided, and if host fairness is enabled, that also means assigning new per-host state to the flow. For this reason, the bulk flow counters of the host(s) assigned to the flow are decremented, before new state is assigned (and the counters, which may not belong to the same host anymore, are incremented again).
Back when this code was introduced, the host fairness mode was always enabled, so the decrement was unconditional. When the configuration flags were introduced the *increment* was made conditional, but the *decrement* was not. Which of course can lead to a spurious decrement (and associated wrap-around to U16_MAX).
AFAICT, when host fairness is disabled, the decrement and wrap-around happens as soon as a hash collision occurs (which is not that common in itself, due to the set-associative hashing). However, in most cases this is harmless, as the value is only used when host fairness mode is enabled. So in order to trigger an array overflow, sch_cake has to first be configured with host fairness disabled, and while running in this mode, a hash collision has to occur to cause the overflow. Then, the qdisc has to be reconfigured to enable host fairness, which leads to the array out-of-bounds because the wrapped-around value is retained and used as an array index. It seems that syzbot managed to trigger this, which is quite impressive in its own right.
This patch fixes the issue by introducing the same conditional check on decrement as is used on increment.
The original bug predates the upstreaming of cake, but the commit listed in the Fixes tag touched that code, meaning that this patch won't apply before that.
--- net/sched/sch_cake.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/sched/sch_cake.c +7 -4
@@ -785,12 +785,15 @@ skip_hash:* queue, accept the collision, update the host tags. */ q->way_collisions++; -if (q->flows[outer_hash + k].set ==CAKE_SET_BULK ) { - q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; - q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; - } allocate_src =cake_dsrc (flow_mode); allocate_dst =cake_ddst (flow_mode); + +if (q->flows[outer_hash + k].set ==CAKE_SET_BULK ) { +if (allocate_src) + q->hosts[q->flows[reduced_hash].srchost].srchost_bulk_flow_count--; +if (allocate_dst) + q->hosts[q->flows[reduced_hash].dsthost].dsthost_bulk_flow_count--; + } found:/* reserve queue for future packets in same flow */ reduced_hash = outer_hash + k;
Greg Kroah-Hartman
maintainerPATCH 73/186 nilfs2: fix missing cleanup on rollforward recovery error
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
commit 5787fcaab9eb5930f5378d6a1dd03d916d146622 upstream.
In an error injection test of a routine for mount-time recovery, KASAN found a use-after-free bug.
It turned out that if data recovery was performed using partial logs created by dsync writes, but an error occurred before starting the log writer to create a recovered checkpoint, the inodes whose data had been recovered were left in the ns_dirty_files list of the nilfs object and were not freed.
Fix this issue by cleaning up inodes that have read the recovery data if the recovery routine fails midway before the log writer starts.
--- fs/nilfs2/recovery.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-)
fs/nilfs2/recovery.c +33 -2
@@ -709,6 +709,33 @@ static void nilfs_finish_roll_forward(st }/** +* nilfs_abort_roll_forward - cleaning up after a failed rollforward recovery +* @nilfs: nilfs object +*/ +static void nilfs_abort_roll_forward (struct the_nilfs *nilfs) +{ +struct nilfs_inode_info *ii, *n; +LIST_HEAD (head); + +/* Abandon inodes that have read recovery data */ +spin_lock (&nilfs->ns_inode_lock); +list_splice_init (&nilfs->ns_dirty_files, &head); +spin_unlock (&nilfs->ns_inode_lock); +if (list_empty (&head)) +return ; + +set_nilfs_purging (nilfs); +list_for_each_entry_safe (ii, n, &head, i_dirty) { +spin_lock (&nilfs->ns_inode_lock); +list_del_init (&ii->i_dirty); +spin_unlock (&nilfs->ns_inode_lock); + +iput (&ii->vfs_inode); + } +clear_nilfs_purging (nilfs); +} + +/** * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint * @nilfs: nilfs object * @sb: super block instance
@@ -766,15 +793,19 @@ int nilfs_salvage_orphan_logs(struct theif (unlikely (err)) {nilfs_err (sb,"error %d writing segment for recovery" , err); - goto failed; + goto put_root; }nilfs_finish_roll_forward (nilfs, ri); } - failed: +put_root:nilfs_put_root (root);return err; + +failed: +nilfs_abort_roll_forward (nilfs); + goto put_root; }/**
Greg Kroah-Hartman
maintainerPATCH 74/186 nilfs2: fix state management in error path of log writing function
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryusuke Konishi <[email protected]>
commit 6576dd6695f2afca3f4954029ac4a64f82ba60ab upstream.
After commit a694291a6211 ("nilfs2: separate wait function from nilfs_segctor_write") was applied, the log writing function nilfs_segctor_do_construct() was able to issue I/O requests continuously even if user data blocks were split into multiple logs across segments, but two potential flaws were introduced in its error handling.
First, if nilfs_segctor_begin_construction() fails while creating the second or subsequent logs, the log writing function returns without calling nilfs_segctor_abort_construction(), so the writeback flag set on pages/folios will remain uncleared. This causes page cache operations to hang waiting for the writeback flag. For example, truncate_inode_pages_final(), which is called via nilfs_evict_inode() when an inode is evicted from memory, will hang.
Second, the NILFS_I_COLLECTED flag set on normal inodes remain uncleared. As a result, if the next log write involves checkpoint creation, that's fine, but if a partial log write is performed that does not, inodes with NILFS_I_COLLECTED set are erroneously removed from the "sc_dirty_files" list, and their data and b-tree blocks may not be written to the device, corrupting the block mapping.
Fix these issues by uniformly calling nilfs_segctor_abort_construction() on failure of each step in the loop in nilfs_segctor_do_construct(), having it clean up logs and segment usages according to progress, and correcting the conditions for calling nilfs_redirty_inodes() to ensure that the NILFS_I_COLLECTED flag is cleared.
--- fs/nilfs2/segment.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/nilfs2/segment.c +6 -4
@@ -1833,6 +1833,9 @@ static void nilfs_segctor_abort_construcnilfs_abort_logs (&logs, ret ? : err);list_splice_tail_init (&sci->sc_segbufs, &logs); +if (list_empty (&logs)) +return ;/* if the first segment buffer preparation failed */ +nilfs_cancel_segusage (&logs, nilfs->ns_sufile);nilfs_free_incomplete_logs (&logs, nilfs);
@@ -2077,7 +2080,7 @@ static int nilfs_segctor_do_construct(st err =nilfs_segctor_begin_construction (sci, nilfs);if (unlikely (err)) - goto out; + goto failed;/* Update time stamp */ sci->sc_seg_ctime =ktime_get_real_seconds ();
@@ -2140,10 +2143,9 @@ static int nilfs_segctor_do_construct(streturn err; failed_to_write: -if (sci->sc_stage.flags &NILFS_CF_IFILE_STARTED ) -nilfs_redirty_inodes (&sci->sc_dirty_files); - failed: +if (mode ==SC_LSEG_SR &&nilfs_sc_cstage_get (sci) >=NILFS_ST_IFILE ) +nilfs_redirty_inodes (&sci->sc_dirty_files);if (nilfs_doing_gc ())nilfs_redirty_inodes (&sci->sc_gc_inodes);nilfs_segctor_abort_construction (sci, nilfs, err);
Greg Kroah-Hartman
maintainerPATCH 75/186 btrfs: fix use-after-free after failure to create a snapshot
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 28b21c558a3753171097193b6f6602a94169093a upstream.
At ioctl.c:create_snapshot(), we allocate a pending snapshot structure and then attach it to the transaction's list of pending snapshots. After that we call btrfs_commit_transaction(), and if that returns an error we jump to 'fail' label, where we kfree() the pending snapshot structure. This can result in a later use-after-free of the pending snapshot:
1) We allocated the pending snapshot and added it to the transaction's list of pending snapshots;
2) We call btrfs_commit_transaction(), and it fails either at the first call to btrfs_run_delayed_refs() or btrfs_start_dirty_block_groups(). In both cases, we don't abort the transaction and we release our transaction handle. We jump to the 'fail' label and free the pending snapshot structure. We return with the pending snapshot still in the transaction's list;
3) Another task commits the transaction. This time there's no error at all, and then during the transaction commit it accesses a pointer to the pending snapshot structure that the snapshot creation task has already freed, resulting in a user-after-free.
This issue could actually be detected by smatch, which produced the following warning:
fs/btrfs/ioctl.c:843 create_snapshot() warn: '&pending_snapshot->list' not removed from list
So fix this by not having the snapshot creation ioctl directly add the pending snapshot to the transaction's list. Instead add the pending snapshot to the transaction handle, and then at btrfs_commit_transaction() we add the snapshot to the list only when we can guarantee that any error returned after that point will result in a transaction abort, in which case the ioctl code can safely free the pending snapshot and no one can access it anymore.
--- fs/btrfs/ioctl.c | 5 +---- fs/btrfs/transaction.c | 24 ++++++++++++++++++++++++ fs/btrfs/transaction.h | 2 ++ 3 files changed, 27 insertions(+), 4 deletions(-)
fs/btrfs/ioctl.c +1 -4
@@ -853,10 +853,7 @@ static int create_snapshot(struct btrfs_ goto fail; } -spin_lock (&fs_info->trans_lock); -list_add (&pending_snapshot->list, - &trans->transaction->pending_snapshots); -spin_unlock (&fs_info->trans_lock); + trans->pending_snapshot = pending_snapshot; ret =btrfs_commit_transaction (trans);if (ret)
fs/btrfs/transaction.c +24 -0
@@ -2075,6 +2075,27 @@ static inline void btrfs_wait_delalloc_f } } +/* +* Add a pending snapshot associated with the given transaction handle to the +* respective handle. This must be called after the transaction commit started +* and while holding fs_info->trans_lock. +* This serves to guarantee a caller of btrfs_commit_transaction() that it can +* safely free the pending snapshot pointer in case btrfs_commit_transaction() +* returns an error. +*/ +static void add_pending_snapshot (struct btrfs_trans_handle *trans) +{ +struct btrfs_transaction *cur_trans = trans->transaction; + +if (!trans->pending_snapshot) +return ; + +lockdep_assert_held (&trans->fs_info->trans_lock); +ASSERT (cur_trans->state >=TRANS_STATE_COMMIT_START ); + +list_add (&trans->pending_snapshot->list, &cur_trans->pending_snapshots); +} +int btrfs_commit_transaction (struct btrfs_trans_handle *trans) {struct btrfs_fs_info *fs_info = trans->fs_info;
@@ -2161,6 +2182,8 @@ int btrfs_commit_transaction(struct btrfspin_lock (&fs_info->trans_lock);if (cur_trans->state >=TRANS_STATE_COMMIT_START ) { +add_pending_snapshot (trans); +spin_unlock (&fs_info->trans_lock);refcount_inc (&cur_trans->use_count); ret =btrfs_end_transaction (trans);
@@ -2243,6 +2266,7 @@ int btrfs_commit_transaction(struct btrf* COMMIT_DOING so make sure to wait for num_writers to == 1 again. */ spin_lock (&fs_info->trans_lock); +add_pending_snapshot (trans); cur_trans->state =TRANS_STATE_COMMIT_DOING ;spin_unlock (&fs_info->trans_lock); wait_event(cur_trans->writer_wait,
fs/btrfs/transaction.h +2 -0
@@ -122,6 +122,8 @@ struct btrfs_trans_handle {struct btrfs_transaction *transaction;struct btrfs_block_rsv *block_rsv;struct btrfs_block_rsv *orig_rsv; +/* Set by a task that wants to create a snapshot. */ +struct btrfs_pending_snapshot *pending_snapshot;refcount_t use_count;unsigned int type;/*
Greg Kroah-Hartman
maintainerPATCH 76/186 mptcp: pr_debug: add missing \n at the end
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
commit cb41b195e634d3f1ecfcd845314e64fd4bb3c7aa upstream.
pr_debug() have been added in various places in MPTCP code to help developers to debug some situations. With the dynamic debug feature, it is easy to enable all or some of them, and asks users to reproduce issues with extra debug.
Many of these pr_debug() don't end with a new line, while no 'pr_cont()' are used in MPTCP code. So the goal was not to display multiple debug messages on one line: they were then not missing the '\n' on purpose. Not having the new line at the end causes these messages to be printed with a delay, when something else needs to be printed. This issue is not visible when many messages need to be printed, but it is annoying and confusing when only specific messages are expected, e.g.
# echo "func mptcp_pm_add_addr_echoed +fmp" \
> /sys/kernel/debug/dynamic_debug/control
# ./mptcp_join.sh "signal address"; \
echo "$(awk '{print $1}' /proc/uptime) - end"; \
sleep 5s; \
echo "$(awk '{print $1}' /proc/uptime) - restart"; \
./mptcp_join.sh "signal address"
013 signal address
(...)
10.75 - end
15.76 - restart
013 signal address
[ 10.367935] mptcp:mptcp_pm_add_addr_echoed: MPTCP: msk=(...)
(...) => a delay of 5 seconds: printed with a 10.36 ts, but after 'restart'
which was printed at the 15.76 ts.
The 'Fixes' tag here below points to the first pr_debug() used without '\n' in net/mptcp. This patch could be split in many small ones, with different Fixes tag, but it doesn't seem worth it, because it is easy to re-generate this patch with this simple 'sed' command:
git grep -l pr_debug -- net/mptcp |
xargs sed -i "s/\(pr_debug(\".*[^n]\)\(\"[,)]\)/\1\\\n\2/g"
So in case of conflicts, simply drop the modifications, and launch this command.
[ As mentioned above, conflicts were expected, and resolved by using the
'sed' command which is visible above. ]
--- net/mptcp/options.c | 34 +++++++++++++++--------------- net/mptcp/pm.c | 24 ++++++++++----------- net/mptcp/pm_netlink.c | 14 ++++++------ net/mptcp/protocol.c | 54 ++++++++++++++++++++++++------------------------- net/mptcp/protocol.h | 4 +-- net/mptcp/subflow.c | 50 ++++++++++++++++++++++----------------------- 6 files changed, 90 insertions(+), 90 deletions(-)
net/mptcp/options.c +17 -17
@@ -96,7 +96,7 @@ static void mptcp_parse_option(const str mp_opt->data_len =get_unaligned_be16 (ptr); ptr +=2 ; } -pr_debug ("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d" , +pr_debug ("MP_CAPABLE version=%x, flags=%x, optlen=%d sndr=%llu, rcvr=%llu len=%d\n" , version, flags, opsize, mp_opt->sndr_key, mp_opt->rcvr_key, mp_opt->data_len);break ;
@@ -110,7 +110,7 @@ static void mptcp_parse_option(const str ptr +=4 ; mp_opt->nonce =get_unaligned_be32 (ptr); ptr +=4 ; -pr_debug ("MP_JOIN bkup=%u, id=%u, token=%u, nonce=%u" , +pr_debug ("MP_JOIN bkup=%u, id=%u, token=%u, nonce=%u\n" , mp_opt->backup, mp_opt->join_id, mp_opt->token, mp_opt->nonce); }else if (opsize ==TCPOLEN_MPTCP_MPJ_SYNACK ) {
@@ -120,20 +120,20 @@ static void mptcp_parse_option(const str ptr +=8 ; mp_opt->nonce =get_unaligned_be32 (ptr); ptr +=4 ; -pr_debug ("MP_JOIN bkup=%u, id=%u, thmac=%llu, nonce=%u" , +pr_debug ("MP_JOIN bkup=%u, id=%u, thmac=%llu, nonce=%u\n" , mp_opt->backup, mp_opt->join_id, mp_opt->thmac, mp_opt->nonce); }else if (opsize ==TCPOLEN_MPTCP_MPJ_ACK ) { ptr +=2 ;memcpy (mp_opt->hmac, ptr,MPTCPOPT_HMAC_LEN ); -pr_debug ("MP_JOIN hmac" ); +pr_debug ("MP_JOIN hmac\n" ); }else { mp_opt->mp_join =0 ; }break ;case MPTCPOPT_DSS : -pr_debug ("DSS" ); +pr_debug ("DSS\n" ); ptr++;/* we must clear 'mpc_map' be able to detect MP_CAPABLE
@@ -148,7 +148,7 @@ static void mptcp_parse_option(const str mp_opt->ack64 = (flags &MPTCP_DSS_ACK64 ) !=0 ; mp_opt->use_ack = (flags &MPTCP_DSS_HAS_ACK ); -pr_debug ("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d" , +pr_debug ("data_fin=%d dsn64=%d use_map=%d ack64=%d use_ack=%d\n" , mp_opt->data_fin, mp_opt->dsn64, mp_opt->use_map, mp_opt->ack64, mp_opt->use_ack);
@@ -189,7 +189,7 @@ static void mptcp_parse_option(const str ptr +=4 ; } -pr_debug ("data_ack=%llu" , mp_opt->data_ack); +pr_debug ("data_ack=%llu\n" , mp_opt->data_ack); }if (mp_opt->use_map) {
@@ -207,7 +207,7 @@ static void mptcp_parse_option(const str mp_opt->data_len =get_unaligned_be16 (ptr); ptr +=2 ; -pr_debug ("data_seq=%llu subflow_seq=%u data_len=%u" , +pr_debug ("data_seq=%llu subflow_seq=%u data_len=%u\n" , mp_opt->data_seq, mp_opt->subflow_seq, mp_opt->data_len); }
@@ -242,7 +242,7 @@ static void mptcp_parse_option(const str mp_opt->add_addr =1 ; mp_opt->addr_id = *ptr++; -pr_debug ("ADD_ADDR: id=%d, echo=%d" , mp_opt->addr_id, mp_opt->echo); +pr_debug ("ADD_ADDR: id=%d, echo=%d\n" , mp_opt->addr_id, mp_opt->echo);if (mp_opt->family ==MPTCP_ADDR_IPVERSION_4 ) {memcpy ((u8 *)&mp_opt->addr.s_addr, (u8 *)ptr,4 ); ptr +=4 ;
@@ -277,7 +277,7 @@ static void mptcp_parse_option(const str mp_opt->rm_addr =1 ; mp_opt->rm_id = *ptr++; -pr_debug ("RM_ADDR: id=%d" , mp_opt->rm_id); +pr_debug ("RM_ADDR: id=%d\n" , mp_opt->rm_id);break ;default :
@@ -344,7 +344,7 @@ bool mptcp_syn_options(struct sock *sk, *size =TCPOLEN_MPTCP_MPC_SYN ;return true; }else if (subflow->request_join) { -pr_debug ("remote_token=%u, nonce=%u" , subflow->remote_token, +pr_debug ("remote_token=%u, nonce=%u\n" , subflow->remote_token, subflow->local_nonce); opts->suboptions =OPTION_MPTCP_MPJ_SYN ; opts->join_id = subflow->local_id;
@@ -436,7 +436,7 @@ static bool mptcp_established_options_mpelse *size =TCPOLEN_MPTCP_MPC_ACK ; -pr_debug ("subflow=%p, local_key=%llu, remote_key=%llu map_len=%d" , +pr_debug ("subflow=%p, local_key=%llu, remote_key=%llu map_len=%d\n" , subflow, subflow->local_key, subflow->remote_key, data_len);
@@ -445,7 +445,7 @@ static bool mptcp_established_options_mp opts->suboptions =OPTION_MPTCP_MPJ_ACK ;memcpy (opts->hmac, subflow->hmac,MPTCPOPT_HMAC_LEN ); *size =TCPOLEN_MPTCP_MPJ_ACK ; -pr_debug ("subflow=%p" , subflow); +pr_debug ("subflow=%p\n" , subflow);schedule_3rdack_retransmission (sk);return true;
@@ -619,7 +619,7 @@ static bool mptcp_established_options_ad } }#endif -pr_debug ("addr_id=%d, ahmac=%llu, echo=%d" , opts->addr_id, opts->ahmac, echo); +pr_debug ("addr_id=%d, ahmac=%llu, echo=%d\n" , opts->addr_id, opts->ahmac, echo);return true; }
@@ -644,7 +644,7 @@ static bool mptcp_established_options_rm opts->suboptions |=OPTION_MPTCP_RM_ADDR ; opts->rm_id = rm_id; -pr_debug ("rm_id=%d" , opts->rm_id); +pr_debug ("rm_id=%d\n" , opts->rm_id);return true; }
@@ -703,7 +703,7 @@ bool mptcp_synack_options(const struct r opts->suboptions =OPTION_MPTCP_MPC_SYNACK ; opts->sndr_key = subflow_req->local_key; *size =TCPOLEN_MPTCP_MPC_SYNACK ; -pr_debug ("subflow_req=%p, local_key=%llu" , +pr_debug ("subflow_req=%p, local_key=%llu\n" , subflow_req, subflow_req->local_key);return true; }else if (subflow_req->mp_join) {
@@ -712,7 +712,7 @@ bool mptcp_synack_options(const struct r opts->join_id = subflow_req->local_id; opts->thmac = subflow_req->thmac; opts->nonce = subflow_req->local_nonce; -pr_debug ("req=%p, bkup=%u, id=%u, thmac=%llu, nonce=%u" , +pr_debug ("req=%p, bkup=%u, id=%u, thmac=%llu, nonce=%u\n" , subflow_req, opts->backup, opts->join_id, opts->thmac, opts->nonce); *size =TCPOLEN_MPTCP_MPJ_SYNACK ;
net/mptcp/pm.c +12 -12
@@ -16,7 +16,7 @@ int mptcp_pm_announce_addr(struct mptcp_ const struct mptcp_addr_info *addr, bool echo) { - pr_debug("msk=%p, local_id=%d", msk, addr->id); + pr_debug("msk=%p, local_id=%d\n", msk, addr->id); msk->pm.local = *addr;WRITE_ONCE (msk->pm.add_addr_echo, echo);
@@ -26,7 +26,7 @@ int mptcp_pm_announce_addr(struct mptcp_int mptcp_pm_remove_addr (struct mptcp_sock *msk,u8 local_id) { -pr_debug ("msk=%p, local_id=%d" , msk, local_id); +pr_debug ("msk=%p, local_id=%d\n" , msk, local_id); msk->pm.rm_id = local_id;WRITE_ONCE (msk->pm.rm_addr_signal, true);
@@ -35,7 +35,7 @@ int mptcp_pm_remove_addr(struct mptcp_soint mptcp_pm_remove_subflow (struct mptcp_sock *msk,u8 local_id) { -pr_debug ("msk=%p, local_id=%d" , msk, local_id); +pr_debug ("msk=%p, local_id=%d\n" , msk, local_id);spin_lock_bh (&msk->pm.lock);mptcp_pm_nl_rm_subflow_received (msk, local_id);
@@ -49,7 +49,7 @@ void mptcp_pm_new_connection(struct mptc {struct mptcp_pm_data *pm = &msk->pm; -pr_debug ("msk=%p, token=%u side=%d" , msk, msk->token, server_side); +pr_debug ("msk=%p, token=%u side=%d\n" , msk, msk->token, server_side);WRITE_ONCE (pm->server_side, server_side); }
@@ -59,7 +59,7 @@ bool mptcp_pm_allow_new_subflow(struct mstruct mptcp_pm_data *pm = &msk->pm;int ret =0 ; -pr_debug ("msk=%p subflows=%d max=%d allow=%d" , msk, pm->subflows, +pr_debug ("msk=%p subflows=%d max=%d allow=%d\n" , msk, pm->subflows, pm->subflows_max,READ_ONCE (pm->accept_subflow));/* try to avoid acquiring the lock below */
@@ -83,7 +83,7 @@ bool mptcp_pm_allow_new_subflow(struct mstatic bool mptcp_pm_schedule_work (struct mptcp_sock *msk,enum mptcp_pm_status new_status) { -pr_debug ("msk=%p status=%x new=%lx" , msk, msk->pm.status, +pr_debug ("msk=%p status=%x new=%lx\n" , msk, msk->pm.status,BIT (new_status));if (msk->pm.status &BIT (new_status))return false;
@@ -98,7 +98,7 @@ void mptcp_pm_fully_established(struct m {struct mptcp_pm_data *pm = &msk->pm; -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk);/* try to avoid acquiring the lock below */ if (!READ_ONCE (pm->work_pending))
@@ -114,7 +114,7 @@ void mptcp_pm_fully_established(struct mvoid mptcp_pm_connection_closed (struct mptcp_sock *msk) { -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk); } void mptcp_pm_subflow_established(struct mptcp_sock *msk,
@@ -122,7 +122,7 @@ void mptcp_pm_subflow_established(struct {struct mptcp_pm_data *pm = &msk->pm; -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk);if (!READ_ONCE (pm->work_pending))return ;
@@ -137,7 +137,7 @@ void mptcp_pm_subflow_established(structvoid mptcp_pm_subflow_closed (struct mptcp_sock *msk,u8 id) { -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk); } void mptcp_pm_add_addr_received(struct mptcp_sock *msk,
@@ -145,7 +145,7 @@ void mptcp_pm_add_addr_received(struct m {struct mptcp_pm_data *pm = &msk->pm; -pr_debug ("msk=%p remote_id=%d accept=%d" , msk, addr->id, +pr_debug ("msk=%p remote_id=%d accept=%d\n" , msk, addr->id,READ_ONCE (pm->accept_addr));spin_lock_bh (&pm->lock);
@@ -162,7 +162,7 @@ void mptcp_pm_rm_addr_received(struct mp {struct mptcp_pm_data *pm = &msk->pm; -pr_debug ("msk=%p remote_id=%d" , msk, rm_id); +pr_debug ("msk=%p remote_id=%d\n" , msk, rm_id);spin_lock_bh (&pm->lock);mptcp_pm_schedule_work (msk,MPTCP_PM_RM_ADDR_RECEIVED );
net/mptcp/pm_netlink.c +7 -7
@@ -206,7 +206,7 @@ static void mptcp_pm_add_timer(struct tistruct mptcp_sock *msk = entry->sock;struct sock *sk = (struct sock *)msk; -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk);if (!msk)return ;
@@ -225,7 +225,7 @@ static void mptcp_pm_add_timer(struct tispin_lock_bh (&msk->pm.lock);if (!mptcp_pm_should_add_signal (msk)) { -pr_debug ("retransmit ADD_ADDR id=%d" , entry->addr.id); +pr_debug ("retransmit ADD_ADDR id=%d\n" , entry->addr.id);mptcp_pm_announce_addr (msk, &entry->addr, false); entry->retrans_times++; }
@@ -289,7 +289,7 @@ void mptcp_pm_free_anno_list(struct mptcstruct sock *sk = (struct sock *)msk;LIST_HEAD (free_list); -pr_debug ("msk=%p" , msk); +pr_debug ("msk=%p\n" , msk);spin_lock_bh (&msk->pm.lock);list_splice_init (&msk->pm.anno_list, &free_list);
@@ -372,7 +372,7 @@ void mptcp_pm_nl_add_addr_received(strucstruct mptcp_addr_info local;int err; -pr_debug ("accepted %d:%d remote family %d" , +pr_debug ("accepted %d:%d remote family %d\n" , msk->pm.add_addr_accepted, msk->pm.add_addr_accept_max, msk->pm.remote.family); msk->pm.subflows++;
@@ -405,7 +405,7 @@ void mptcp_pm_nl_rm_addr_received(structstruct mptcp_subflow_context *subflow, *tmp;struct sock *sk = (struct sock *)msk; -pr_debug ("address rm_id %d" , msk->pm.rm_id); +pr_debug ("address rm_id %d\n" , msk->pm.rm_id);if (!msk->pm.rm_id)return ;
@@ -441,7 +441,7 @@ void mptcp_pm_nl_rm_subflow_received(strstruct mptcp_subflow_context *subflow, *tmp;struct sock *sk = (struct sock *)msk; -pr_debug ("subflow rm_id %d" , rm_id); +pr_debug ("subflow rm_id %d\n" , rm_id);if (!rm_id)return ;
@@ -791,7 +791,7 @@ static int mptcp_nl_remove_subflow_and_sstruct mptcp_sock *msk;long s_slot =0 , s_num =0 ; -pr_debug ("remove_id=%d" , addr->id); +pr_debug ("remove_id=%d\n" , addr->id);while ((msk =mptcp_token_iter_next (net, &s_slot, &s_num)) !=NULL ) {struct sock *sk = (struct sock *)msk;
net/mptcp/protocol.c +27 -27
209 lines not on this page · raw message
net/mptcp/protocol.h +2 -2
@@ -523,7 +523,7 @@ static inline bool mptcp_check_fallback(static inline void __mptcp_do_fallback (struct mptcp_sock *msk) {if (test_bit (MPTCP_FALLBACK_DONE , &msk->flags)) { -pr_debug ("TCP fallback already done (msk=%p)" , msk); +pr_debug ("TCP fallback already done (msk=%p)\n" , msk);return ; }set_bit (MPTCP_FALLBACK_DONE , &msk->flags);
@@ -537,7 +537,7 @@ static inline void mptcp_do_fallback(str__mptcp_do_fallback (msk); } -#define pr_fallback (a) pr_debug("%s:fallback to TCP (msk=%p)", __func__, a) +#define pr_fallback (a) pr_debug("%s:fallback to TCP (msk=%p)\n", __func__, a)static inline bool subflow_simultaneous_connect (struct sock *sk) {
net/mptcp/subflow.c +25 -25
200 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 77/186 mptcp: pm: avoid possible UaF when selecting endp
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Matthieu Baerts (NGI0)" <[email protected]>
commit 48e50dcbcbaaf713d82bf2da5c16aeced94ad07d upstream.
select_local_address() and select_signal_address() both select an endpoint entry from the list inside an RCU protected section, but return a reference to it, to be read later on. If the entry is dereferenced after the RCU unlock, reading info could cause a Use-after-Free.
A simple solution is to copy the required info while inside the RCU protected section to avoid any risk of UaF later. The address ID might need to be modified later to handle the ID0 case later, so a copy seems OK to deal with.
[ Conflicts in pm_netlink.c, because quite a bit of new code has been
added around since commit 86e39e04482b ("mptcp: keep track of local endpoint still available for each msk"), and commit 2843ff6f36db ("mptcp: remote addresses fullmesh"). But the issue is still there. The conflicts have been resolved using the same way: by adding a new parameter to select_local_address() and select_signal_address(), and use it instead of the pointer they were previously returning. The code is simpler in this version, this conflict resolution looks safe. ]
--- net/mptcp/pm_netlink.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-)
net/mptcp/pm_netlink.c +25 -20
@@ -127,11 +127,13 @@ static bool lookup_subflow_by_saddr(consreturn false; } -static struct mptcp_pm_addr_entry * +static bool select_local_address (const struct pm_nl_pernet *pernet, -struct mptcp_sock *msk) +struct mptcp_sock *msk, +struct mptcp_pm_addr_entry *new_entry) { -struct mptcp_pm_addr_entry *entry, *ret =NULL ; +struct mptcp_pm_addr_entry *entry; +bool found = false;rcu_read_lock ();spin_lock_bh (&msk->join_list_lock);
@@ -145,19 +147,23 @@ select_local_address(const struct pm_nl_if (entry->addr.family == ((struct sock *)msk)->sk_family && !lookup_subflow_by_saddr (&msk->conn_list, &entry->addr) && !lookup_subflow_by_saddr (&msk->join_list, &entry->addr)) { - ret = entry; + *new_entry = *entry; + found = true;break ; } }spin_unlock_bh (&msk->join_list_lock);rcu_read_unlock (); -return ret; + +return found; } -static struct mptcp_pm_addr_entry * -select_signal_address (struct pm_nl_pernet *pernet,unsigned int pos) +static bool +select_signal_address (struct pm_nl_pernet *pernet,unsigned int pos, +struct mptcp_pm_addr_entry *new_entry) { -struct mptcp_pm_addr_entry *entry, *ret =NULL ; +struct mptcp_pm_addr_entry *entry; +bool found = false;int i =0 ;rcu_read_lock ();
@@ -170,12 +176,14 @@ select_signal_address(struct pm_nl_perneif (!(entry->addr.flags &MPTCP_PM_ADDR_FLAG_SIGNAL ))continue ;if (i++ == pos) { - ret = entry; + *new_entry = *entry; + found = true;break ; } }rcu_read_unlock (); -return ret; + +return found; }static void check_work_pending (struct mptcp_sock *msk)
@@ -305,7 +313,7 @@ static void mptcp_pm_create_subflow_or_s {struct mptcp_addr_info remote = {0 };struct sock *sk = (struct sock *)msk; -struct mptcp_pm_addr_entry *local; +struct mptcp_pm_addr_entry local;struct pm_nl_pernet *pernet; pernet =net_generic (sock_net ((struct sock *)msk), pm_nl_pernet_id);
@@ -317,13 +325,11 @@ static void mptcp_pm_create_subflow_or_s/* check first for announce */ if (msk->pm.add_addr_signaled < msk->pm.add_addr_signal_max) { - local =select_signal_address (pernet, - msk->pm.add_addr_signaled); - -if (local) { -if (mptcp_pm_alloc_anno_list (msk, local)) { +if (select_signal_address (pernet, msk->pm.add_addr_signaled, + &local)) { +if (mptcp_pm_alloc_anno_list (msk, &local)) { msk->pm.add_addr_signaled++; -mptcp_pm_announce_addr (msk, &local->addr, false); +mptcp_pm_announce_addr (msk, &local.addr, false); } }else {/* pick failed, avoid fourther attempts later */
@@ -338,13 +344,12 @@ static void mptcp_pm_create_subflow_or_s msk->pm.subflows < msk->pm.subflows_max) {remote_address ((struct sock_common *)sk, &remote); - local =select_local_address (pernet, msk); -if (local) { +if (select_local_address (pernet, msk, &local)) { msk->pm.local_addr_used++; msk->pm.subflows++;check_work_pending (msk);spin_unlock_bh (&msk->pm.lock); -__mptcp_subflow_connect (sk, &local->addr, &remote); +__mptcp_subflow_connect (sk, &local.addr, &remote);spin_lock_bh (&msk->pm.lock);return ; }
Greg Kroah-Hartman
maintainerPATCH 78/186 nfsd: move reply cache initialization into nfsd startup
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit f5f9d4a314da88c0a5faa6d168bf69081b7a25ae ]
There's no need to start the reply cache before nfsd is up and running, and doing so means that we register a shrinker for every net namespace instead of just the ones where nfsd is running.
Move it to the per-net nfsd startup instead.
Stable-dep-of: ed9ab7346e90 ("nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net")
--- fs/nfsd/nfsctl.c | 8 -------- fs/nfsd/nfssvc.c | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-)
fs/nfsd/nfsctl.c +0 -8
@@ -1461,16 +1461,11 @@ static __net_init int nfsd_init_net(stru nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn); - retval =nfsd_reply_cache_init (nn); -if (retval) - goto out_cache_error;get_random_bytes (&nn->siphash_key,sizeof (nn->siphash_key));seqlock_init (&nn->writeverf_lock);return 0 ; -out_cache_error: -nfsd_idmap_shutdown (net); out_idmap_error:nfsd_export_shutdown (net); out_export_error:
@@ -1479,9 +1474,6 @@ out_export_error: static __net_exit void nfsd_exit_net(struct net *net) { -struct nfsd_net *nn =net_generic (net, nfsd_net_id); - -nfsd_reply_cache_shutdown (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);nfsd_netns_free_versions (net_generic (net, nfsd_net_id));
fs/nfsd/nfssvc.c +9 -1
@@ -427,16 +427,23 @@ static int nfsd_startup_net(struct net * ret =nfsd_file_cache_start_net (net);if (ret) goto out_lockd; - ret =nfs4_state_start_net (net); + + ret =nfsd_reply_cache_init (nn);if (ret) goto out_filecache; + ret =nfs4_state_start_net (net); +if (ret) + goto out_reply_cache; +#ifdef CONFIG_NFSD_V4_2_INTER_SSC nfsd4_ssc_init_umount_work (nn);#endif nn->nfsd_net_up = true;return 0 ; +out_reply_cache: +nfsd_reply_cache_shutdown (nn); out_filecache:nfsd_file_cache_shutdown_net (net); out_lockd:
@@ -454,6 +461,7 @@ static void nfsd_shutdown_net(struct netstruct nfsd_net *nn =net_generic (net, nfsd_net_id);nfs4_state_shutdown_net (net); +nfsd_reply_cache_shutdown (nn);nfsd_file_cache_shutdown_net (net);if (nn->lockd_up) {lockd_down (net);
Greg Kroah-Hartman
maintainerPATCH 79/186 nfsd: move init of percpu reply_cache_stats counters back to nfsd_init_net
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
[ Upstream commit ed9ab7346e908496816cffdecd46932035f66e2e ]
Commit f5f9d4a314da ("nfsd: move reply cache initialization into nfsd startup") moved the initialization of the reply cache into nfsd startup, but didn't account for the stats counters, which can be accessed before nfsd is ever started. The result can be a NULL pointer dereference when someone accesses /proc/fs/nfsd/reply_cache_stats while nfsd is still shut down.
This is a regression and a user-triggerable oops in the right situation:
- non-x86_64 arch
- /proc/fs/nfsd is mounted in the namespace
- nfsd is not started in the namespace
- unprivileged user calls "cat /proc/fs/nfsd/reply_cache_stats"
Although this is easy to trigger on some arches (like aarch64), on x86_64, calling this_cpu_ptr(NULL) evidently returns a pointer to the fixed_percpu_data. That struct looks just enough like a newly initialized percpu var to allow nfsd_reply_cache_stats_show to access it without Oopsing.
Move the initialization of the per-net+per-cpu reply-cache counters back into nfsd_init_net, while leaving the rest of the reply cache allocations to be done at nfsd startup time.
Kudos to Eirik who did most of the legwork to track this down.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/cache.h | 2 ++ fs/nfsd/nfscache.c | 25 ++++++++++++++----------- fs/nfsd/nfsctl.c | 10 +++++++++- 3 files changed, 25 insertions(+), 12 deletions(-)
fs/nfsd/cache.h +2 -0
@@ -80,6 +80,8 @@ enum {int nfsd_drc_slab_create (void );void nfsd_drc_slab_free (void ); +int nfsd_net_reply_cache_init (struct nfsd_net *nn); +void nfsd_net_reply_cache_destroy (struct nfsd_net *nn);int nfsd_reply_cache_init (struct nfsd_net *);void nfsd_reply_cache_shutdown (struct nfsd_net *);int nfsd_cache_lookup (struct svc_rqst *);
fs/nfsd/nfscache.c +14 -11
@@ -148,12 +148,23 @@ void nfsd_drc_slab_free(void)kmem_cache_destroy (drc_slab); } -static int nfsd_reply_cache_stats_init (struct nfsd_net *nn) +/** +* nfsd_net_reply_cache_init - per net namespace reply cache set-up +* @nn: nfsd_net being initialized +* +* Returns zero on succes; otherwise a negative errno is returned. +*/ +int nfsd_net_reply_cache_init (struct nfsd_net *nn) {return nfsd_percpu_counters_init (nn->counter,NFSD_NET_COUNTERS_NUM ); } -static void nfsd_reply_cache_stats_destroy (struct nfsd_net *nn) +/** +* nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down +* @nn: nfsd_net being freed +* +*/ +void nfsd_net_reply_cache_destroy (struct nfsd_net *nn) {nfsd_percpu_counters_destroy (nn->counter,NFSD_NET_COUNTERS_NUM ); }
@@ -169,16 +180,12 @@ int nfsd_reply_cache_init(struct nfsd_ne hashsize =nfsd_hashsize (nn->max_drc_entries); nn->maskbits =ilog2 (hashsize); - status =nfsd_reply_cache_stats_init (nn); -if (status) - goto out_nomem; - nn->nfsd_reply_cache_shrinker.scan_objects = nfsd_reply_cache_scan; nn->nfsd_reply_cache_shrinker.count_objects = nfsd_reply_cache_count; nn->nfsd_reply_cache_shrinker.seeks =1 ; status =register_shrinker (&nn->nfsd_reply_cache_shrinker);if (status) - goto out_stats_destroy; +return status; nn->drc_hashtbl =kvzalloc (array_size (hashsize,sizeof (*nn->drc_hashtbl)),GFP_KERNEL );
@@ -194,9 +201,6 @@ int nfsd_reply_cache_init(struct nfsd_nereturn 0 ; out_shrinker:unregister_shrinker (&nn->nfsd_reply_cache_shrinker); -out_stats_destroy: -nfsd_reply_cache_stats_destroy (nn); -out_nomem:printk (KERN_ERR "nfsd: failed to allocate reply cache\n" );return -ENOMEM ; }
@@ -216,7 +220,6 @@ void nfsd_reply_cache_shutdown(struct nf rp, nn); } } -nfsd_reply_cache_stats_destroy (nn);kvfree (nn->drc_hashtbl); nn->drc_hashtbl =NULL ;
fs/nfsd/nfsctl.c +9 -1
@@ -1458,6 +1458,9 @@ static __net_init int nfsd_init_net(stru retval =nfsd_idmap_init (net);if (retval) goto out_idmap_error; + retval =nfsd_net_reply_cache_init (nn); +if (retval) + goto out_repcache_error; nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn);
@@ -1466,6 +1469,8 @@ static __net_init int nfsd_init_net(strureturn 0 ; +out_repcache_error: +nfsd_idmap_shutdown (net); out_idmap_error:nfsd_export_shutdown (net); out_export_error:
@@ -1474,9 +1479,12 @@ out_export_error: static __net_exit void nfsd_exit_net(struct net *net) { +struct nfsd_net *nn =net_generic (net, nfsd_net_id); + +nfsd_net_reply_cache_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net); -nfsd_netns_free_versions (net_generic (net, nfsd_net_id)); +nfsd_netns_free_versions (nn); }static struct pernet_operations nfsd_net_ops = {
Greg Kroah-Hartman
maintainerPATCH 80/186 NFSD: Refactor nfsd_reply_cache_free_locked()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 35308e7f0fc3942edc87d9c6dc78c4a096428957 ]
To reduce contention on the bucket locks, we must avoid calling kfree() while each bucket lock is held.
Start by refactoring nfsd_reply_cache_free_locked() into a helper that removes an entry from the bucket (and must therefore run under the lock) and a second helper that frees the entry (which does not need to hold the lock).
For readability, rename the helpers nfsd_cacherep_<verb>.
Stable-dep-of: a9507f6af145 ("NFSD: Replace nfsd_prune_bucket()")
--- fs/nfsd/nfscache.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
fs/nfsd/nfscache.c +20 -7
@@ -110,21 +110,33 @@ nfsd_reply_cache_alloc(struct svc_rqst *return rp; } +static void nfsd_cacherep_free (struct svc_cacherep *rp) +{ +if (rp->c_type ==RC_REPLBUFF ) +kfree (rp->c_replvec.iov_base); +kmem_cache_free (drc_slab, rp); +} +static void -nfsd_reply_cache_free_locked (struct nfsd_drc_bucket *b,struct svc_cacherep *rp, -struct nfsd_net *nn) +nfsd_cacherep_unlink_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b, +struct svc_cacherep *rp) { -if (rp->c_type ==RC_REPLBUFF && rp->c_replvec.iov_base) { +if (rp->c_type ==RC_REPLBUFF && rp->c_replvec.iov_base)nfsd_stats_drc_mem_usage_sub (nn, rp->c_replvec.iov_len); -kfree (rp->c_replvec.iov_base); - }if (rp->c_state !=RC_UNUSED ) {rb_erase (&rp->c_node, &b->rb_head);list_del (&rp->c_lru);atomic_dec (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_sub (nn,sizeof (*rp)); } -kmem_cache_free (drc_slab, rp); +} + +static void +nfsd_reply_cache_free_locked (struct nfsd_drc_bucket *b,struct svc_cacherep *rp, +struct nfsd_net *nn) +{ +nfsd_cacherep_unlink_locked (nn, b, rp); +nfsd_cacherep_free (rp); } static void
@@ -132,8 +144,9 @@ nfsd_reply_cache_free(struct nfsd_drc_bu struct nfsd_net *nn) {spin_lock (&b->cache_lock); -nfsd_reply_cache_free_locked (b, rp, nn); +nfsd_cacherep_unlink_locked (nn, b, rp);spin_unlock (&b->cache_lock); +nfsd_cacherep_free (rp); }int nfsd_drc_slab_create (void )
Greg Kroah-Hartman
maintainerPATCH 81/186 NFSD: Rename nfsd_reply_cache_alloc()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit ff0d169329768c1102b7b07eebe5a9839aa1c143 ]
For readability, rename to match the other helpers.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/nfscache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/nfsd/nfscache.c +3 -3
@@ -85,8 +85,8 @@ nfsd_hashsize(unsigned int limit) }static struct svc_cacherep * -nfsd_reply_cache_alloc (struct svc_rqst *rqstp,__wsum csum, -struct nfsd_net *nn) +nfsd_cacherep_alloc (struct svc_rqst *rqstp,__wsum csum, +struct nfsd_net *nn) {struct svc_cacherep *rp;
@@ -457,7 +457,7 @@ int nfsd_cache_lookup(struct svc_rqst *r* preallocate an entry. */ nn =net_generic (SVC_NET (rqstp), nfsd_net_id); - rp =nfsd_reply_cache_alloc (rqstp, csum, nn); + rp =nfsd_cacherep_alloc (rqstp, csum, nn);if (!rp) goto out;
Greg Kroah-Hartman
maintainerPATCH 82/186 NFSD: Replace nfsd_prune_bucket()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit a9507f6af1450ed26a4a36d979af518f5bb21e5d ]
Enable nfsd_prune_bucket() to drop the bucket lock while calling kfree(). Use the same pattern that Jeff recently introduced in the NFSD filecache.
A few percpu operations are moved outside the lock since they temporarily disable local IRQs which is expensive and does not need to be done while the lock is held.
Stable-dep-of: c135e1269f34 ("NFSD: Refactor the duplicate reply cache shrinker")
--- fs/nfsd/nfscache.c | 78 ++++++++++++++++++++++++++++++++++++++++++----------- fs/nfsd/trace.h | 22 ++++++++++++++ 2 files changed, 85 insertions(+), 15 deletions(-)
fs/nfsd/nfscache.c +63 -15
@@ -117,6 +117,21 @@ static void nfsd_cacherep_free(struct svkmem_cache_free (drc_slab, rp); } +static unsigned long +nfsd_cacherep_dispose (struct list_head *dispose) +{ +struct svc_cacherep *rp; +unsigned long freed =0 ; + +while (!list_empty (dispose)) { + rp = list_first_entry(dispose, struct svc_cacherep, c_lru); +list_del (&rp->c_lru); +nfsd_cacherep_free (rp); + freed++; + } +return freed; +} +static void nfsd_cacherep_unlink_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b,struct svc_cacherep *rp)
@@ -259,6 +274,41 @@ nfsd_cache_bucket_find(__be32 xid, strucreturn &nn->drc_hashtbl[hash]; } +/* +* Remove and return no more than @max expired entries in bucket @b. +* If @max is zero, do not limit the number of removed entries. +*/ +static void +nfsd_prune_bucket_locked (struct nfsd_net *nn,struct nfsd_drc_bucket *b, +unsigned int max,struct list_head *dispose) +{ +unsigned long expiry = jiffies -RC_EXPIRE ; +struct svc_cacherep *rp, *tmp; +unsigned int freed =0 ; + +lockdep_assert_held (&b->cache_lock); + +/* The bucket LRU is ordered oldest-first. */ +list_for_each_entry_safe (rp, tmp, &b->lru_head, c_lru) { +/* +* Don't free entries attached to calls that are still +* in-progress, but do keep scanning the list. +*/ +if (rp->c_state ==RC_INPROG ) +continue ; + +if (atomic_read (&nn->num_drc_entries) <= nn->max_drc_entries && +time_before (expiry, rp->c_timestamp)) +break ; + +nfsd_cacherep_unlink_locked (nn, b, rp); +list_add (&rp->c_lru, dispose); + +if (max && ++freed > max) +break ; + } +} +static long prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn,unsigned int max) {
@@ -282,11 +332,6 @@ static long prune_bucket(struct nfsd_drcreturn freed; } -static long nfsd_prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn) -{ -return prune_bucket (b, nn,3 ); -} -/* * Walk the LRU list and prune off entries that are older than RC_EXPIRE. * Also prune the oldest ones when the total exceeds the max number of entries.
@@ -442,6 +487,8 @@ int nfsd_cache_lookup(struct svc_rqst *r__wsum csum;struct nfsd_drc_bucket *b;int type = rqstp->rq_cachetype; +unsigned long freed; +LIST_HEAD (dispose);int rtn =RC_DOIT ; rqstp->rq_cacherep =NULL ;
@@ -466,20 +513,18 @@ int nfsd_cache_lookup(struct svc_rqst *r found =nfsd_cache_insert (b, rp, nn);if (found != rp) goto found_entry; - -nfsd_stats_rc_misses_inc (); rqstp->rq_cacherep = rp; rp->c_state =RC_INPROG ; +nfsd_prune_bucket_locked (nn, b,3 , &dispose); +spin_unlock (&b->cache_lock); + freed =nfsd_cacherep_dispose (&dispose); +trace_nfsd_drc_gc (nn, freed); + +nfsd_stats_rc_misses_inc ();atomic_inc (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_add (nn,sizeof (*rp)); - -nfsd_prune_bucket (b, nn); - -out_unlock: -spin_unlock (&b->cache_lock); -out: -return rtn; + goto out; found_entry:/* We found a matching entry which is either in progress or done. */
@@ -517,7 +562,10 @@ found_entry: out_trace:trace_nfsd_drc_found (nn, rqstp, rtn); - goto out_unlock; +out_unlock: +spin_unlock (&b->cache_lock); +out: +return rtn; }/**
fs/nfsd/trace.h +22 -0
@@ -1171,6 +1171,28 @@ TRACE_EVENT(nfsd_drc_mismatch, __entry->ingress) ); +TRACE_EVENT_CONDITION (nfsd_drc_gc, +TP_PROTO ( + const struct nfsd_net *nn, + unsigned long freed + ), +TP_ARGS (nn, freed), +TP_CONDITION (freed >0 ), +TP_STRUCT__entry ( + __field(unsigned long long, boot_time) + __field(unsigned long, freed) +__field (int, total) + ), +TP_fast_assign ( + __entry->boot_time = nn->boot_time; + __entry->freed = freed; + __entry->total = atomic_read(&nn->num_drc_entries); + ), +TP_printk ("boot_time=%16llx total=%d freed=%lu" , + __entry->boot_time, __entry->total, __entry->freed + ) +); + TRACE_EVENT(nfsd_cb_args, TP_PROTO( const struct nfs4_client *clp,
Greg Kroah-Hartman
maintainerPATCH 83/186 NFSD: Refactor the duplicate reply cache shrinker
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit c135e1269f34dfdea4bd94c11060c83a3c0b3c12 ]
Avoid holding the bucket lock while freeing cache entries. This change also caps the number of entries that are freed when the shrinker calls to reduce the shrinker's impact on the cache's effectiveness.
--- fs/nfsd/nfscache.c | 82 +++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 43 deletions(-)
fs/nfsd/nfscache.c +39 -43
@@ -309,68 +309,64 @@ nfsd_prune_bucket_locked(struct nfsd_net } } -static long prune_bucket (struct nfsd_drc_bucket *b,struct nfsd_net *nn, -unsigned int max) +/** +* nfsd_reply_cache_count - count_objects method for the DRC shrinker +* @shrink: our registered shrinker context +* @sc: garbage collection parameters +* +* Returns the total number of entries in the duplicate reply cache. To +* keep things simple and quick, this is not the number of expired entries +* in the cache (ie, the number that would be removed by a call to +* nfsd_reply_cache_scan). +*/ +static unsigned long +nfsd_reply_cache_count (struct shrinker *shrink,struct shrink_control *sc) { -struct svc_cacherep *rp, *tmp; -long freed =0 ; +struct nfsd_net *nn =container_of (shrink, + struct nfsd_net, nfsd_reply_cache_shrinker); -list_for_each_entry_safe (rp, tmp, &b->lru_head, c_lru) { -/* -* Don't free entries attached to calls that are still -* in-progress, but do keep scanning the list. -*/ -if (rp->c_state ==RC_INPROG ) -continue ; -if (atomic_read (&nn->num_drc_entries) <= nn->max_drc_entries && -time_before (jiffies, rp->c_timestamp +RC_EXPIRE )) -break ; -nfsd_reply_cache_free_locked (b, rp, nn); -if (max && freed++ > max) -break ; - } -return freed; +return atomic_read (&nn->num_drc_entries); } -/* -* Walk the LRU list and prune off entries that are older than RC_EXPIRE. -* Also prune the oldest ones when the total exceeds the max number of entries. +/** +* nfsd_reply_cache_scan - scan_objects method for the DRC shrinker +* @shrink: our registered shrinker context +* @sc: garbage collection parameters +* +* Free expired entries on each bucket's LRU list until we've released +* nr_to_scan freed objects. Nothing will be released if the cache +* has not exceeded it's max_drc_entries limit. +* +* Returns the number of entries released by this call. */ -static long -prune_cache_entries (struct nfsd_net *nn) +static unsigned long +nfsd_reply_cache_scan (struct shrinker *shrink,struct shrink_control *sc) { +struct nfsd_net *nn =container_of (shrink, + struct nfsd_net, nfsd_reply_cache_shrinker); +unsigned long freed =0 ; +LIST_HEAD (dispose);unsigned int i; -long freed =0 ;for (i =0 ; i < nn->drc_hashsize; i++) {struct nfsd_drc_bucket *b = &nn->drc_hashtbl[i];if (list_empty (&b->lru_head))continue ; +spin_lock (&b->cache_lock); - freed +=prune_bucket (b, nn,0 ); +nfsd_prune_bucket_locked (nn, b,0 , &dispose);spin_unlock (&b->cache_lock); - } -return freed; -} -static unsigned long -nfsd_reply_cache_count (struct shrinker *shrink,struct shrink_control *sc) -{ -struct nfsd_net *nn =container_of (shrink, - struct nfsd_net, nfsd_reply_cache_shrinker); + freed +=nfsd_cacherep_dispose (&dispose); +if (freed > sc->nr_to_scan) +break ; + } -return atomic_read (&nn->num_drc_entries); +trace_nfsd_drc_gc (nn, freed); +return freed; } -static unsigned long -nfsd_reply_cache_scan (struct shrinker *shrink,struct shrink_control *sc) -{ -struct nfsd_net *nn =container_of (shrink, - struct nfsd_net, nfsd_reply_cache_shrinker); - -return prune_cache_entries (nn); -}/* * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes */
Greg Kroah-Hartman
maintainerPATCH 84/186 NFSD: simplify error paths in nfsd_svc()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
[ Upstream commit bf32075256e9dd9c6b736859e2c5813981339908 ]
The error paths in nfsd_svc() are needlessly complex and can result in a final call to svc_put() without nfsd_last_thread() being called. This results in the listening sockets not being closed properly.
The per-netns setup provided by nfsd_startup_new() and removed by nfsd_shutdown_net() is needed precisely when there are running threads. So we don't need nfsd_up_before. We don't need to know if it *was* up. We only need to know if any threads are left. If none are, then we must call nfsd_shutdown_net(). But we don't need to do that explicitly as nfsd_last_thread() does that for us.
So simply call nfsd_last_thread() before the last svc_put() if there are no running threads. That will always do the right thing.
Also discard:
pr_info("nfsd: last server has exited, flushing export cache\n");
It may not be true if an attempt to start the first server failed, and it isn't particularly helpful and it simply reports normal behaviour.
--- fs/nfsd/nfssvc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
fs/nfsd/nfssvc.c +4 -10
@@ -567,7 +567,6 @@ void nfsd_last_thread(struct net *net)return ;nfsd_shutdown_net (net); -pr_info ("nfsd: last server has exited, flushing export cache\n" );nfsd_export_flush (net); }
@@ -782,7 +781,6 @@ int nfsd_svc(int nrservs, struct net *net, const struct cred *cred) { int error; -bool nfsd_up_before;struct nfsd_net *nn =net_generic (net, nfsd_net_id);struct svc_serv *serv;
@@ -802,8 +800,6 @@ nfsd_svc(int nrservs, struct net *net, c error =nfsd_create_serv (net);if (error) goto out; - - nfsd_up_before = nn->nfsd_net_up; serv = nn->nfsd_serv; error =nfsd_startup_net (net, cred);
@@ -811,17 +807,15 @@ nfsd_svc(int nrservs, struct net *net, c goto out_put; error =svc_set_num_threads (serv,NULL , nrservs);if (error) - goto out_shutdown; + goto out_put; error = serv->sv_nrthreads; -if (error ==0 ) -nfsd_last_thread (net); -out_shutdown: -if (error <0 && !nfsd_up_before) -nfsd_shutdown_net (net); out_put:/* Threads now hold service active */ if (xchg (&nn->keep_active,0 ))svc_put (serv); + +if (serv->sv_nrthreads ==0 ) +nfsd_last_thread (net);svc_put (serv); out:mutex_unlock (&nfsd_mutex);
Greg Kroah-Hartman
maintainerPATCH 85/186 NFSD: Rewrite synopsis of nfsd_percpu_counters_init()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 5ec39944f874e1ecc09f624a70dfaa8ac3bf9d08 ]
In function ‘export_stats_init’,
inlined from ‘svc_export_alloc’ at fs/nfsd/export.c:866:6:fs/nfsd/export.c:337:16: warning: ‘nfsd_percpu_counters_init’ accessing 40 bytes in a region of size 0 [-Wstringop-overflow=]
337 | return nfsd_percpu_counters_init(&stats->counter, EXP_STATS_COUNTERS_NUM);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/nfsd/export.c:337:16: note: referencing argument 1 of type ‘struct percpu_counter[0]’
fs/nfsd/stats.h: In function ‘svc_export_alloc’:
fs/nfsd/stats.h:40:5: note: in a call to function ‘nfsd_percpu_counters_init’
40 | int nfsd_percpu_counters_init(struct percpu_counter counters[], int num);
| ^~~~~~~~~~~~~~~~~~~~~~~~~Stable-dep-of: 93483ac5fec6 ("nfsd: expose /proc/net/sunrpc/nfsd in net namespaces")
--- fs/nfsd/stats.c | 2 +- fs/nfsd/stats.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
fs/nfsd/stats.c +1 -1
@@ -74,7 +74,7 @@ static int nfsd_show(struct seq_file *seDEFINE_PROC_SHOW_ATTRIBUTE (nfsd); -int nfsd_percpu_counters_init (struct percpu_counter counters[],int num) +int nfsd_percpu_counters_init (struct percpu_counter *counters,int num) {int i, err =0 ;
fs/nfsd/stats.h +3 -3
@@ -36,9 +36,9 @@ extern struct nfsd_stats nfsdstats;extern struct svc_stat nfsd_svcstats; -int nfsd_percpu_counters_init (struct percpu_counter counters[],int num); -void nfsd_percpu_counters_reset (struct percpu_counter counters[],int num); -void nfsd_percpu_counters_destroy (struct percpu_counter counters[],int num); +int nfsd_percpu_counters_init (struct percpu_counter *counters,int num); +void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num); +void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num);int nfsd_stat_init (void );void nfsd_stat_shutdown (void );
Greg Kroah-Hartman
maintainerPATCH 86/186 NFSD: Fix frame size warning in svc_export_parse()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit 6939ace1f22681fface7841cdbf34d3204cc94b5 ]
fs/nfsd/export.c: In function 'svc_export_parse':fs/nfsd/export.c:737:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
737 | }
On my systems, svc_export_parse() has a stack frame of over 800 bytes, not 1040, but nonetheless, it could do with some reduction.
When a struct svc_export is on the stack, it's a temporary structure used as an argument, and not visible as an actual exported FS. No need to reserve space for export_stats in such cases.
Stable-dep-of: 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace")
--- fs/nfsd/export.c | 32 +++++++++++++++++++++++--------- fs/nfsd/export.h | 4 ++-- fs/nfsd/stats.h | 12 ++++++------ 3 files changed, 31 insertions(+), 17 deletions(-)
fs/nfsd/export.c +23 -9
@@ -339,12 +339,16 @@ static int export_stats_init(struct expostatic void export_stats_reset (struct export_stats *stats) { -nfsd_percpu_counters_reset (stats->counter,EXP_STATS_COUNTERS_NUM ); +if (stats) +nfsd_percpu_counters_reset (stats->counter, +EXP_STATS_COUNTERS_NUM ); }static void export_stats_destroy (struct export_stats *stats) { -nfsd_percpu_counters_destroy (stats->counter,EXP_STATS_COUNTERS_NUM ); +if (stats) +nfsd_percpu_counters_destroy (stats->counter, +EXP_STATS_COUNTERS_NUM ); }static void svc_export_put (struct kref *ref)
@@ -353,7 +357,8 @@ static void svc_export_put(struct kref *path_put (&exp->ex_path);auth_domain_put (exp->ex_client);nfsd4_fslocs_free (&exp->ex_fslocs); -export_stats_destroy (&exp->ex_stats); +export_stats_destroy (exp->ex_stats); +kfree (exp->ex_stats);kfree (exp->ex_uuid);kfree_rcu (exp, ex_rcu); }
@@ -738,13 +743,15 @@ static int svc_export_show(struct seq_fiseq_putc (m,'\t' );seq_escape (m, exp->ex_client->name," \t\n\\" );if (export_stats) { -seq_printf (m,"\t%lld\n" , exp->ex_stats.start_time); +struct percpu_counter *counter = exp->ex_stats->counter; + +seq_printf (m,"\t%lld\n" , exp->ex_stats->start_time);seq_printf (m,"\tfh_stale: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_FH_STALE ])); +percpu_counter_sum_positive (&counter[EXP_STATS_FH_STALE ]));seq_printf (m,"\tio_read: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_READ ])); +percpu_counter_sum_positive (&counter[EXP_STATS_IO_READ ]));seq_printf (m,"\tio_write: %lld\n" , -percpu_counter_sum_positive (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ])); +percpu_counter_sum_positive (&counter[EXP_STATS_IO_WRITE ]));seq_putc (m,'\n' );return 0 ; }
@@ -790,7 +797,7 @@ static void svc_export_init(struct cache new->ex_layout_types =0 ; new->ex_uuid =NULL ; new->cd = item->cd; -export_stats_reset (&new->ex_stats); +export_stats_reset (new->ex_stats); }static void export_update (struct cache_head *cnew,struct cache_head *citem)
@@ -826,7 +833,14 @@ static struct cache_head *svc_export_allif (!i)return NULL ; -if (export_stats_init (&i->ex_stats)) { + i->ex_stats =kmalloc (sizeof (*(i->ex_stats)),GFP_KERNEL ); +if (!i->ex_stats) { +kfree (i); +return NULL ; + } + +if (export_stats_init (i->ex_stats)) { +kfree (i->ex_stats);kfree (i);return NULL ; }
fs/nfsd/export.h +2 -2
@@ -64,10 +64,10 @@ struct svc_export {struct cache_head h;struct auth_domain * ex_client;int ex_flags; +int ex_fsid;struct path ex_path;kuid_t ex_anon_uid;kgid_t ex_anon_gid; -int ex_fsid;unsigned char * ex_uuid;/* 16 byte fsid */ struct nfsd4_fs_locations ex_fslocs;uint32_t ex_nflavors;
@@ -76,7 +76,7 @@ struct svc_export {struct nfsd4_deviceid_map *ex_devid_map;struct cache_detail *cd;struct rcu_head ex_rcu; -struct export_stats ex_stats; +struct export_stats *ex_stats; };/* an "export key" (expkey) maps a filehandlefragement to an
fs/nfsd/stats.h +6 -6
@@ -60,22 +60,22 @@ static inline void nfsd_stats_rc_nocachestatic inline void nfsd_stats_fh_stale_inc (struct svc_export *exp) {percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_FH_STALE ]); -if (exp) -percpu_counter_inc (&exp->ex_stats.counter[EXP_STATS_FH_STALE ]); +if (exp && exp->ex_stats) +percpu_counter_inc (&exp->ex_stats->counter[EXP_STATS_FH_STALE ]); }static inline void nfsd_stats_io_read_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_READ ], amount); -if (exp) -percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_READ ], amount); +if (exp && exp->ex_stats) +percpu_counter_add (&exp->ex_stats->counter[EXP_STATS_IO_READ ], amount); }static inline void nfsd_stats_io_write_add (struct svc_export *exp,s64 amount) {percpu_counter_add (&nfsdstats.counter[NFSD_STATS_IO_WRITE ], amount); -if (exp) -percpu_counter_add (&exp->ex_stats.counter[EXP_STATS_IO_WRITE ], amount); +if (exp && exp->ex_stats) +percpu_counter_add (&exp->ex_stats->counter[EXP_STATS_IO_WRITE ], amount); }static inline void nfsd_stats_payload_misses_inc (struct nfsd_net *nn)
Greg Kroah-Hartman
maintainerPATCH 87/186 sunrpc: dont change ->sv_stats if it doesnt exist
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit ab42f4d9a26f1723dcfd6c93fcf768032b2bb5e7 ]
We check for the existence of ->sv_stats elsewhere except in the core processing code. It appears that only nfsd actual exports these values anywhere, everybody else just has a write only copy of sv_stats in their svc_program. Add a check for ->sv_stats before every adjustment to allow us to eliminate the stats struct from all the users who don't report the stats.
--- net/sunrpc/svc.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
net/sunrpc/svc.c +16 -8
@@ -1355,7 +1355,8 @@ svc_process_common(struct svc_rqst *rqst goto err_bad_proc;/* Syntactic check complete */ - serv->sv_stats->rpccnt++; +if (serv->sv_stats) + serv->sv_stats->rpccnt++;trace_svc_process (rqstp, progp->pg_name);/* Build the reply header. */
@@ -1421,7 +1422,8 @@ err_short_len: goto close_xprt; err_bad_rpc: - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,1 );/* REJECT */ svc_putnl (resv,0 );/* RPC_MISMATCH */ svc_putnl (resv,2 );/* Only RPCv2 supported */
@@ -1434,7 +1436,8 @@ err_release_bad_auth: err_bad_auth:dprintk ("svc: authentication failed (%d)\n" ,be32_to_cpu (rqstp->rq_auth_stat)); - serv->sv_stats->rpcbadauth++; +if (serv->sv_stats) + serv->sv_stats->rpcbadauth++;/* Restore write pointer to location of accept status: */ xdr_ressize_check (rqstp, reply_statp);svc_putnl (resv,1 );/* REJECT */
@@ -1444,7 +1447,8 @@ err_bad_auth: err_bad_prog:dprintk ("svc: unknown program %d\n" , prog); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROG_UNAVAIL ); goto sendit;
@@ -1452,7 +1456,8 @@ err_bad_vers:svc_printk (rqstp,"unknown version (%d for prog %d, %s)\n" , rqstp->rq_vers, rqstp->rq_prog, progp->pg_name); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROG_MISMATCH );svc_putnl (resv, process.mismatch.lovers);svc_putnl (resv, process.mismatch.hivers);
@@ -1461,7 +1466,8 @@ err_bad_vers: err_bad_proc:svc_printk (rqstp,"unknown procedure (%d)\n" , rqstp->rq_proc); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,RPC_PROC_UNAVAIL ); goto sendit;
@@ -1470,7 +1476,8 @@ err_garbage: rpc_stat = rpc_garbage_args; err_bad: - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++;svc_putnl (resv,ntohl (rpc_stat)); goto sendit; }
@@ -1505,7 +1512,8 @@ svc_process(struct svc_rqst *rqstp)if (dir !=0 ) {/* direction != CALL */ svc_printk (rqstp,"bad direction %d, dropping request\n" , dir); - serv->sv_stats->rpcbadfmt++; +if (serv->sv_stats) + serv->sv_stats->rpcbadfmt++; goto out_drop; }
Greg Kroah-Hartman
maintainerPATCH 88/186 nfsd: stop setting ->pg_stats for unused stats
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit a2214ed588fb3c5b9824a21cff870482510372bb ]
A lot of places are setting a blank svc_stats in ->pg_stats and never utilizing these stats. Remove all of these extra structs as we're not reporting these stats anywhere.
--- fs/lockd/svc.c | 3 --- fs/nfs/callback.c | 3 --- fs/nfsd/nfssvc.c | 5 ----- 3 files changed, 11 deletions(-)
fs/lockd/svc.c +0 -3
@@ -759,8 +759,6 @@ static const struct svc_version *nlmsvc_#endif }; -static struct svc_stat nlmsvc_stats; -#define NLM_NRVERS ARRAY_SIZE(nlmsvc_version)static struct svc_program nlmsvc_program = { .pg_prog =NLM_PROGRAM ,/* program number */
@@ -768,7 +766,6 @@ static struct svc_program nlmsvc_program .pg_vers = nlmsvc_version, /* version table */ .pg_name = "lockd", /* service name */ .pg_class = "nfsd", /* share authentication with nfsd */ - .pg_stats = &nlmsvc_stats, /* stats table */ .pg_authenticate = &lockd_authenticate, /* export authentication */ .pg_init_request = svc_generic_init_request, .pg_rpcbind_set = svc_generic_rpcbind_set,
fs/nfs/callback.c +0 -3
@@ -407,15 +407,12 @@ static const struct svc_version *nfs4_ca [4] = &nfs4_callback_version4, }; -static struct svc_stat nfs4_callback_stats; -static struct svc_program nfs4_callback_program = { .pg_prog =NFS4_CALLBACK ,/* RPC service number */ .pg_nvers =ARRAY_SIZE (nfs4_callback_version),/* Number of entries */ .pg_vers = nfs4_callback_version,/* version table */ .pg_name ="NFSv4 callback" ,/* service name */ .pg_class ="nfs" ,/* authentication class */ - .pg_stats = &nfs4_callback_stats, .pg_authenticate = nfs_callback_authenticate, .pg_init_request = svc_generic_init_request, .pg_rpcbind_set = svc_generic_rpcbind_set,
fs/nfsd/nfssvc.c +0 -5
@@ -89,7 +89,6 @@ unsigned long nfsd_drc_max_mem;unsigned long nfsd_drc_mem_used;#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL ) -static struct svc_stat nfsd_acl_svcstats;static const struct svc_version *nfsd_acl_version[] = { # if defined(CONFIG_NFSD_V2_ACL) [2] = &nfsd_acl_version2,
@@ -108,15 +107,11 @@ static struct svc_program nfsd_acl_progr .pg_vers = nfsd_acl_version, .pg_name = "nfsacl", .pg_class = "nfsd", - .pg_stats = &nfsd_acl_svcstats, .pg_authenticate = &svc_set_client, .pg_init_request = nfsd_acl_init_request, .pg_rpcbind_set = nfsd_acl_rpcbind_set, }; -static struct svc_stat nfsd_acl_svcstats = { - .program = &nfsd_acl_program, -};#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ static const struct svc_version *nfsd_version[] = {
Greg Kroah-Hartman
maintainerPATCH 89/186 sunrpc: pass in the sv_stats struct through svc_create_pooled
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit f094323867668d50124886ad884b665de7319537 ]
Since only one service actually reports the rpc stats there's not much of a reason to have a pointer to it in the svc_program struct. Adjust the svc_create_pooled function to take the sv_stats as an argument and pass the struct through there as desired instead of getting it from the svc_program->pg_stats.
--- fs/nfsd/nfssvc.c | 3 ++- include/linux/sunrpc/svc.h | 4 +++- net/sunrpc/svc.c | 12 +++++++----- 3 files changed, 12 insertions(+), 7 deletions(-)
fs/nfsd/nfssvc.c +2 -1
@@ -664,7 +664,8 @@ int nfsd_create_serv(struct net *net)if (nfsd_max_blksize ==0 ) nfsd_max_blksize =nfsd_get_default_max_blksize ();nfsd_reset_versions (nn); - serv =svc_create_pooled (&nfsd_program, nfsd_max_blksize, nfsd); + serv =svc_create_pooled (&nfsd_program, &nfsd_svcstats, + nfsd_max_blksize, nfsd);if (serv ==NULL )return -ENOMEM ;
include/linux/sunrpc/svc.h +3 -1
@@ -484,7 +484,9 @@ void svc_rqst_replace_page(struct sv struct page *page);void svc_rqst_free (struct svc_rqst *);void svc_exit_thread (struct svc_rqst *); -struct svc_serv *svc_create_pooled (struct svc_program *,unsigned int , +struct svc_serv *svc_create_pooled (struct svc_program *prog, +struct svc_stat *stats, +unsigned int bufsize,int (*threadfn)(void *data));int svc_set_num_threads (struct svc_serv *,struct svc_pool *,int );int svc_pool_stats_open (struct svc_serv *serv,struct file *file);
net/sunrpc/svc.c +7 -5
@@ -445,8 +445,8 @@ __svc_init_bc(struct svc_serv *serv)* Create an RPC service */ static struct svc_serv * -__svc_create (struct svc_program *prog,unsigned int bufsize,int npools, -int (*threadfn)(void *data)) +__svc_create (struct svc_program *prog,struct svc_stat *stats, +unsigned int bufsize,int npools,int (*threadfn)(void *data)) {struct svc_serv *serv;unsigned int vers;
@@ -458,7 +458,7 @@ __svc_create(struct svc_program *prog, u serv->sv_name = prog->pg_name; serv->sv_program = prog;kref_init (&serv->sv_refcnt); - serv->sv_stats = prog->pg_stats; + serv->sv_stats = stats;if (bufsize >RPCSVC_MAXPAYLOAD ) bufsize =RPCSVC_MAXPAYLOAD ; serv->sv_max_payload = bufsize? bufsize :4096 ;
@@ -520,26 +520,28 @@ __svc_create(struct svc_program *prog, ustruct svc_serv *svc_create (struct svc_program *prog,unsigned int bufsize,int (*threadfn)(void *data)) { -return __svc_create (prog, bufsize,1 , threadfn); +return __svc_create (prog,NULL , bufsize,1 , threadfn); }EXPORT_SYMBOL_GPL (svc_create);/** * svc_create_pooled - Create an RPC service with pooled threads * @prog: the RPC program the new service will handle +* @stats: the stats struct if desired * @bufsize: maximum message size for @prog * @threadfn: a function to service RPC requests for @prog * * Returns an instantiated struct svc_serv object or NULL. */ struct svc_serv *svc_create_pooled (struct svc_program *prog, +struct svc_stat *stats,unsigned int bufsize,int (*threadfn)(void *data)) {struct svc_serv *serv;unsigned int npools =svc_pool_map_get (); - serv =__svc_create (prog, bufsize, npools, threadfn); + serv =__svc_create (prog, stats, bufsize, npools, threadfn);if (!serv) goto out_err;return serv;
Greg Kroah-Hartman
maintainerPATCH 90/186 sunrpc: remove ->pg_stats from svc_program
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 3f6ef182f144dcc9a4d942f97b6a8ed969f13c95 ]
Now that this isn't used anywhere, remove it.
--- fs/nfsd/nfssvc.c | 1 - include/linux/sunrpc/svc.h | 1 - 2 files changed, 2 deletions(-)
fs/nfsd/nfssvc.c +0 -1
@@ -136,7 +136,6 @@ struct svc_program nfsd_program = { .pg_vers = nfsd_version, /* version table */ .pg_name = "nfsd", /* program name */ .pg_class = "nfsd", /* authentication class */ - .pg_stats = &nfsd_svcstats, /* version table */ .pg_authenticate = &svc_set_client, /* export authentication */ .pg_init_request = nfsd_init_request, .pg_rpcbind_set = nfsd_rpcbind_set,
include/linux/sunrpc/svc.h +0 -1
@@ -410,7 +410,6 @@ struct svc_program {const struct svc_version **pg_vers;/* version array */ char * pg_name;/* service name */ char * pg_class;/* class name: services sharing authentication */ -struct svc_stat * pg_stats;/* rpc statistics */ int (*pg_authenticate)(struct svc_rqst *); __be32 (*pg_init_request)(struct svc_rqst *, const struct svc_program *,
Greg Kroah-Hartman
maintainerPATCH 91/186 sunrpc: use the struct net as the svc proc private
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 418b9687dece5bd763c09b5c27a801a7e3387be9 ]
nfsd is the only thing using this helper, and it doesn't use the private currently. When we switch to per-network namespace stats we will need the struct net * in order to get to the nfsd_net. Use the net as the proc private so we can utilize this when we make the switch over.
--- net/sunrpc/stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/stats.c +1 -1
@@ -309,7 +309,7 @@ EXPORT_SYMBOL_GPL(rpc_proc_unregister);struct proc_dir_entry *svc_proc_register (struct net *net,struct svc_stat *statp,const struct proc_ops *proc_ops) { -return do_register (net, statp->program->pg_name, statp, proc_ops); +return do_register (net, statp->program->pg_name, net, proc_ops); }EXPORT_SYMBOL_GPL (svc_proc_register);
Greg Kroah-Hartman
maintainerPATCH 92/186 nfsd: rename NFSD_NET_* to NFSD_STATS_*
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit d98416cc2154053950610bb6880911e3dcbdf8c5 ]
We're going to merge the stats all into per network namespace in subsequent patches, rename these nn counters to be consistent with the rest of the stats.
--- fs/nfsd/netns.h | 4 ++-- fs/nfsd/nfscache.c | 4 ++-- fs/nfsd/stats.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-)
fs/nfsd/netns.h +2 -2
@@ -25,9 +25,9 @@ struct nfsd4_client_tracking_ops;enum {/* cache misses due only to checksum comparison failures */ -NFSD_NET_PAYLOAD_MISSES , +NFSD_STATS_PAYLOAD_MISSES ,/* amount of memory (in bytes) currently consumed by the DRC */ -NFSD_NET_DRC_MEM_USAGE , +NFSD_STATS_DRC_MEM_USAGE ,NFSD_NET_COUNTERS_NUM };
fs/nfsd/nfscache.c +2 -2
@@ -673,7 +673,7 @@ int nfsd_reply_cache_stats_show(struct s atomic_read(&nn->num_drc_entries));seq_printf (m,"hash buckets: %u\n" ,1 << nn->maskbits);seq_printf (m,"mem usage: %lld\n" , -percpu_counter_sum_positive (&nn->counter[NFSD_NET_DRC_MEM_USAGE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ]));seq_printf (m,"cache hits: %lld\n" ,percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ])); seq_printf(m, "cache misses: %lld\n",
@@ -681,7 +681,7 @@ int nfsd_reply_cache_stats_show(struct sseq_printf (m,"not cached: %lld\n" ,percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ]));seq_printf (m,"payload misses: %lld\n" , -percpu_counter_sum_positive (&nn->counter[NFSD_NET_PAYLOAD_MISSES ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]));seq_printf (m,"longest chain len: %u\n" , nn->longest_chain);seq_printf (m,"cachesize at longest: %u\n" , nn->longest_chain_cachesize);return 0 ;
fs/nfsd/stats.h +3 -3
@@ -80,17 +80,17 @@ static inline void nfsd_stats_io_write_astatic inline void nfsd_stats_payload_misses_inc (struct nfsd_net *nn) { -percpu_counter_inc (&nn->counter[NFSD_NET_PAYLOAD_MISSES ]); +percpu_counter_inc (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]); }static inline void nfsd_stats_drc_mem_usage_add (struct nfsd_net *nn,s64 amount) { -percpu_counter_add (&nn->counter[NFSD_NET_DRC_MEM_USAGE ], amount); +percpu_counter_add (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ], amount); }static inline void nfsd_stats_drc_mem_usage_sub (struct nfsd_net *nn,s64 amount) { -percpu_counter_sub (&nn->counter[NFSD_NET_DRC_MEM_USAGE ], amount); +percpu_counter_sub (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ], amount); }#endif /* _NFSD_STATS_H */
Greg Kroah-Hartman
maintainerPATCH 93/186 nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 93483ac5fec62cc1de166051b219d953bb5e4ef4 ]
We are running nfsd servers inside of containers with their own network namespace, and we want to monitor these services using the stats found in /proc. However these are not exposed in the proc inside of the container, so we have to bind mount the host /proc into our containers to get at this information.
Separate out the stat counters init and the proc registration, and move the proc registration into the pernet operations entry and exit points so that these stats can be exposed inside of network namespaces.
This is an intermediate step, this just exposes the global counters in the network namespace. Subsequent patches will move these counters into the per-network namespace container.
--- fs/nfsd/nfsctl.c | 8 +++++--- fs/nfsd/stats.c | 21 ++++++--------------- fs/nfsd/stats.h | 6 ++++-- 3 files changed, 15 insertions(+), 20 deletions(-)
fs/nfsd/nfsctl.c +5 -3
@@ -1466,6 +1466,7 @@ static __net_init int nfsd_init_net(strunfsd4_init_leases_net (nn);get_random_bytes (&nn->siphash_key,sizeof (nn->siphash_key));seqlock_init (&nn->writeverf_lock); +nfsd_proc_stat_init (net);return 0 ;
@@ -1481,6 +1482,7 @@ static __net_exit void nfsd_exit_net(str {struct nfsd_net *nn =net_generic (net, nfsd_net_id); +nfsd_proc_stat_shutdown (net);nfsd_net_reply_cache_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);
@@ -1504,7 +1506,7 @@ static int __init init_nfsd(void) retval =nfsd4_init_pnfs ();if (retval) goto out_free_slabs; - retval =nfsd_stat_init ();/* Statistics */ + retval =nfsd_stat_counters_init ();/* Statistics */ if (retval) goto out_free_pnfs; retval =nfsd_drc_slab_create ();
@@ -1540,7 +1542,7 @@ out_free_lockd:nfsd_lockd_shutdown ();nfsd_drc_slab_free (); out_free_stat: -nfsd_stat_shutdown (); +nfsd_stat_counters_destroy (); out_free_pnfs:nfsd4_exit_pnfs (); out_free_slabs:
@@ -1557,7 +1559,7 @@ static void __exit exit_nfsd(void)nfsd_drc_slab_free ();remove_proc_entry ("fs/nfs/exports" ,NULL );remove_proc_entry ("fs/nfs" ,NULL ); -nfsd_stat_shutdown (); +nfsd_stat_counters_destroy ();nfsd_lockd_shutdown ();nfsd4_free_slabs ();nfsd4_exit_pnfs ();
fs/nfsd/stats.c +6 -15
@@ -106,31 +106,22 @@ void nfsd_percpu_counters_destroy(structpercpu_counter_destroy (&counters[i]); } -static int nfsd_stat_counters_init (void ) +int nfsd_stat_counters_init (void ) {return nfsd_percpu_counters_init (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); } -static void nfsd_stat_counters_destroy (void ) +void nfsd_stat_counters_destroy (void ) {nfsd_percpu_counters_destroy (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); } -int nfsd_stat_init (void ) +void nfsd_proc_stat_init (struct net *net) { -int err; - - err =nfsd_stat_counters_init (); -if (err) -return err; - -svc_proc_register (&init_net, &nfsd_svcstats, &nfsd_proc_ops); - -return 0 ; +svc_proc_register (net, &nfsd_svcstats, &nfsd_proc_ops); } -void nfsd_stat_shutdown (void ) +void nfsd_proc_stat_shutdown (struct net *net) { -nfsd_stat_counters_destroy (); -svc_proc_unregister (&init_net,"nfsd" ); +svc_proc_unregister (net,"nfsd" ); }
fs/nfsd/stats.h +4 -2
@@ -39,8 +39,10 @@ extern struct svc_stat nfsd_svcstats;int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num);void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num); -int nfsd_stat_init (void ); -void nfsd_stat_shutdown (void ); +int nfsd_stat_counters_init (void ); +void nfsd_stat_counters_destroy (void ); +void nfsd_proc_stat_init (struct net *net); +void nfsd_proc_stat_shutdown (struct net *net);static inline void nfsd_stats_rc_hits_inc (void ) {
Greg Kroah-Hartman
maintainerPATCH 94/186 nfsd: make all of the nfsd stats per-network namespace
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 4b14885411f74b2b0ce0eb2b39d0fffe54e5ca0d ]
We have a global set of counters that we modify for all of the nfsd operations, but now that we're exposing these stats across all network namespaces we need to make the stats also be per-network namespace. We already have some caching stats that are per-network namespace, so move these definitions into the same counter and then adjust all the helpers and users of these stats to provide the appropriate nfsd_net struct so that the stats are maintained for the per-network namespace objects.
--- fs/nfsd/cache.h | 2 -- fs/nfsd/netns.h | 17 +++++++++++++++-- fs/nfsd/nfs4proc.c | 6 +++--- fs/nfsd/nfscache.c | 36 +++++++----------------------------- fs/nfsd/nfsctl.c | 12 +++--------- fs/nfsd/nfsfh.c | 3 ++- fs/nfsd/stats.c | 24 +++++++++++++----------- fs/nfsd/stats.h | 49 +++++++++++++++++-------------------------------- fs/nfsd/vfs.c | 6 ++++-- 9 files changed, 64 insertions(+), 91 deletions(-)
fs/nfsd/cache.h +0 -2
@@ -80,8 +80,6 @@ enum {int nfsd_drc_slab_create (void );void nfsd_drc_slab_free (void ); -int nfsd_net_reply_cache_init (struct nfsd_net *nn); -void nfsd_net_reply_cache_destroy (struct nfsd_net *nn);int nfsd_reply_cache_init (struct nfsd_net *);void nfsd_reply_cache_shutdown (struct nfsd_net *);int nfsd_cache_lookup (struct svc_rqst *);
fs/nfsd/netns.h +15 -2
@@ -10,6 +10,7 @@#include <net/net_namespace.h> #include <net/netns/generic.h> +#include <linux/nfs4.h> #include <linux/percpu_counter.h> #include <linux/siphash.h>
@@ -28,7 +29,19 @@ enum {NFSD_STATS_PAYLOAD_MISSES ,/* amount of memory (in bytes) currently consumed by the DRC */ NFSD_STATS_DRC_MEM_USAGE , - NFSD_NET_COUNTERS_NUM +NFSD_STATS_RC_HITS ,/* repcache hits */ +NFSD_STATS_RC_MISSES ,/* repcache misses */ +NFSD_STATS_RC_NOCACHE ,/* uncached reqs */ +NFSD_STATS_FH_STALE ,/* FH stale error */ +NFSD_STATS_IO_READ ,/* bytes returned to read requests */ +NFSD_STATS_IO_WRITE ,/* bytes passed in write requests */ +#ifdef CONFIG_NFSD_V4 +NFSD_STATS_FIRST_NFS4_OP ,/* count of individual nfsv4 operations */ +NFSD_STATS_LAST_NFS4_OP =NFSD_STATS_FIRST_NFS4_OP +LAST_NFS4_OP , +#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) +NFSD_STATS_WDELEG_GETATTR ,/* count of getattr conflict with wdeleg */ +#endif +NFSD_STATS_COUNTERS_NUM };/*
@@ -168,7 +181,7 @@ struct nfsd_net {atomic_t num_drc_entries;/* Per-netns stats counters */ -struct percpu_counter counter[NFSD_NET_COUNTERS_NUM ]; +struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM ];/* longest hash chain seen */ unsigned int longest_chain;
fs/nfsd/nfs4proc.c +3 -3
@@ -2435,10 +2435,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp)return rpc_success; } -static inline void nfsd4_increment_op_stats (u32 opnum) +static inline void nfsd4_increment_op_stats (struct nfsd_net *nn,u32 opnum) {if (opnum >=FIRST_NFS4_OP && opnum <=LAST_NFS4_OP ) -percpu_counter_inc (&nfsdstats.counter[NFSD_STATS_NFS4_OP (opnum)]); +percpu_counter_inc (&nn->counter[NFSD_STATS_NFS4_OP (opnum)]); }static const struct nfsd4_operation nfsd4_ops[];
@@ -2713,7 +2713,7 @@ encode_op: status, nfsd4_op_name(op->opnum));nfsd4_cstate_clear_replay (cstate); -nfsd4_increment_op_stats (op->opnum); +nfsd4_increment_op_stats (nn, op->opnum); }fh_put (current_fh);
fs/nfsd/nfscache.c +7 -29
@@ -176,27 +176,6 @@ void nfsd_drc_slab_free(void)kmem_cache_destroy (drc_slab); } -/** -* nfsd_net_reply_cache_init - per net namespace reply cache set-up -* @nn: nfsd_net being initialized -* -* Returns zero on succes; otherwise a negative errno is returned. -*/ -int nfsd_net_reply_cache_init (struct nfsd_net *nn) -{ -return nfsd_percpu_counters_init (nn->counter,NFSD_NET_COUNTERS_NUM ); -} - -/** -* nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down -* @nn: nfsd_net being freed -* -*/ -void nfsd_net_reply_cache_destroy (struct nfsd_net *nn) -{ -nfsd_percpu_counters_destroy (nn->counter,NFSD_NET_COUNTERS_NUM ); -} -int nfsd_reply_cache_init (struct nfsd_net *nn) {unsigned int hashsize;
@@ -478,7 +457,7 @@ out:*/ int nfsd_cache_lookup (struct svc_rqst *rqstp) { -struct nfsd_net *nn; +struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);struct svc_cacherep *rp, *found;__wsum csum;struct nfsd_drc_bucket *b;
@@ -489,7 +468,7 @@ int nfsd_cache_lookup(struct svc_rqst *r rqstp->rq_cacherep =NULL ;if (type ==RC_NOCACHE ) { -nfsd_stats_rc_nocache_inc (); +nfsd_stats_rc_nocache_inc (nn); goto out; }
@@ -499,7 +478,6 @@ int nfsd_cache_lookup(struct svc_rqst *r* Since the common case is a cache miss followed by an insert, * preallocate an entry. */ - nn =net_generic (SVC_NET (rqstp), nfsd_net_id); rp =nfsd_cacherep_alloc (rqstp, csum, nn);if (!rp) goto out;
@@ -517,7 +495,7 @@ int nfsd_cache_lookup(struct svc_rqst *r freed =nfsd_cacherep_dispose (&dispose);trace_nfsd_drc_gc (nn, freed); -nfsd_stats_rc_misses_inc (); +nfsd_stats_rc_misses_inc (nn);atomic_inc (&nn->num_drc_entries);nfsd_stats_drc_mem_usage_add (nn,sizeof (*rp)); goto out;
@@ -525,7 +503,7 @@ int nfsd_cache_lookup(struct svc_rqst *r found_entry:/* We found a matching entry which is either in progress or done. */ nfsd_reply_cache_free_locked (NULL , rp, nn); -nfsd_stats_rc_hits_inc (); +nfsd_stats_rc_hits_inc (nn); rtn =RC_DROPIT ; rp = found;
@@ -675,11 +653,11 @@ int nfsd_reply_cache_stats_show(struct sseq_printf (m,"mem usage: %lld\n" ,percpu_counter_sum_positive (&nn->counter[NFSD_STATS_DRC_MEM_USAGE ]));seq_printf (m,"cache hits: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_HITS ]));seq_printf (m,"cache misses: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_MISSES ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_MISSES ]));seq_printf (m,"not cached: %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_NOCACHE ]));seq_printf (m,"payload misses: %lld\n" ,percpu_counter_sum_positive (&nn->counter[NFSD_STATS_PAYLOAD_MISSES ]));seq_printf (m,"longest chain len: %u\n" , nn->longest_chain);
fs/nfsd/nfsctl.c +3 -9
@@ -1458,7 +1458,7 @@ static __net_init int nfsd_init_net(stru retval =nfsd_idmap_init (net);if (retval) goto out_idmap_error; - retval =nfsd_net_reply_cache_init (nn); + retval =nfsd_stat_counters_init (nn);if (retval) goto out_repcache_error; nn->nfsd_versions =NULL ;
@@ -1483,7 +1483,7 @@ static __net_exit void nfsd_exit_net(strstruct nfsd_net *nn =net_generic (net, nfsd_net_id);nfsd_proc_stat_shutdown (net); -nfsd_net_reply_cache_destroy (nn); +nfsd_stat_counters_destroy (nn);nfsd_idmap_shutdown (net);nfsd_export_shutdown (net);nfsd_netns_free_versions (nn);
@@ -1506,12 +1506,9 @@ static int __init init_nfsd(void) retval =nfsd4_init_pnfs ();if (retval) goto out_free_slabs; - retval =nfsd_stat_counters_init ();/* Statistics */ -if (retval) - goto out_free_pnfs; retval =nfsd_drc_slab_create ();if (retval) - goto out_free_stat; + goto out_free_pnfs;nfsd_lockd_init ();/* lockd->nfsd callbacks */ retval =create_proc_exports_entry ();if (retval)
@@ -1541,8 +1538,6 @@ out_free_exports: out_free_lockd:nfsd_lockd_shutdown ();nfsd_drc_slab_free (); -out_free_stat: -nfsd_stat_counters_destroy (); out_free_pnfs:nfsd4_exit_pnfs (); out_free_slabs:
@@ -1559,7 +1554,6 @@ static void __exit exit_nfsd(void)nfsd_drc_slab_free ();remove_proc_entry ("fs/nfs/exports" ,NULL );remove_proc_entry ("fs/nfs" ,NULL ); -nfsd_stat_counters_destroy ();nfsd_lockd_shutdown ();nfsd4_free_slabs ();nfsd4_exit_pnfs ();
fs/nfsd/nfsfh.c +2 -1
@@ -326,6 +326,7 @@ out:__be32 fh_verify (struct svc_rqst *rqstp,struct svc_fh *fhp,umode_t type,int access) { +struct nfsd_net *nn =net_generic (SVC_NET (rqstp), nfsd_net_id);struct svc_export *exp =NULL ;struct dentry *dentry;__be32 error;
@@ -399,7 +400,7 @@ skip_pseudoflavor_check: } out:if (error == nfserr_stale) -nfsd_stats_fh_stale_inc (exp); +nfsd_stats_fh_stale_inc (nn, exp);return error; }
fs/nfsd/stats.c +13 -11
@@ -34,15 +34,17 @@ struct svc_stat nfsd_svcstats = {static int nfsd_show (struct seq_file *seq,void *v) { +struct net *net =PDE_DATA (file_inode (seq->file)); +struct nfsd_net *nn =net_generic (net, nfsd_net_id);int i;seq_printf (seq,"rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_HITS ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_MISSES ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_RC_NOCACHE ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_FH_STALE ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_IO_READ ]), -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_IO_WRITE ])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_HITS ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_MISSES ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_RC_NOCACHE ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_FH_STALE ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_IO_READ ]), +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_IO_WRITE ]));/* thread usage: */ seq_printf (seq,"th %u 0" ,atomic_read (&nfsdstats.th_cnt));
@@ -63,7 +65,7 @@ static int nfsd_show(struct seq_file *seseq_printf (seq,"proc4ops %u" ,LAST_NFS4_OP +1 );for (i =0 ; i <=LAST_NFS4_OP ; i++) {seq_printf (seq," %lld" , -percpu_counter_sum_positive (&nfsdstats.counter[NFSD_STATS_NFS4_OP (i)])); +percpu_counter_sum_positive (&nn->counter[NFSD_STATS_NFS4_OP (i)])); }seq_putc (seq,'\n' );
@@ -106,14 +108,14 @@ void nfsd_percpu_counters_destroy(structpercpu_counter_destroy (&counters[i]); } -int nfsd_stat_counters_init (void ) +int nfsd_stat_counters_init (struct nfsd_net *nn) { -return nfsd_percpu_counters_init (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); +return nfsd_percpu_counters_init (nn->counter,NFSD_STATS_COUNTERS_NUM ); } -void nfsd_stat_counters_destroy (void ) +void nfsd_stat_counters_destroy (struct nfsd_net *nn) { -nfsd_percpu_counters_destroy (nfsdstats.counter,NFSD_STATS_COUNTERS_NUM ); +nfsd_percpu_counters_destroy (nn->counter,NFSD_STATS_COUNTERS_NUM ); }void nfsd_proc_stat_init (struct net *net)
fs/nfsd/stats.h +17 -32
85 lines not on this page · raw message
fs/nfsd/vfs.c +4 -2
@@ -1000,7 +1000,9 @@ static __be32 nfsd_finish_read(struct sv unsigned long *count, u32 *eof, ssize_t host_err) { if (host_err >= 0) { - nfsd_stats_io_read_add(fhp->fh_export, host_err); + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + +nfsd_stats_io_read_add (nn, fhp->fh_export, host_err); *eof =nfsd_eof_on_read (file, offset, host_err, *count); *count = host_err;fsnotify_access (file);
@@ -1143,7 +1145,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s goto out_nfserr; } *cnt = host_err; -nfsd_stats_io_write_add (exp, *cnt); +nfsd_stats_io_write_add (nn, exp, *cnt);fsnotify_modify (file); host_err =filemap_check_wb_err (file->f_mapping, since);if (host_err <0 )
Greg Kroah-Hartman
maintainerPATCH 95/186 nfsd: remove nfsd_stats, make th_cnt a global counter
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit e41ee44cc6a473b1f414031782c3b4283d7f3e5f ]
This is the last global stat, take it out of the nfsd_stats struct and make it a global part of nfsd, report it the same as always.
--- fs/nfsd/nfsd.h | 1 + fs/nfsd/nfssvc.c | 5 +++-- fs/nfsd/stats.c | 3 +-- fs/nfsd/stats.h | 6 ------ 4 files changed, 5 insertions(+), 10 deletions(-)
fs/nfsd/nfsd.h +1 -0
@@ -69,6 +69,7 @@ extern struct mutex nfsd_mutex;extern spinlock_t nfsd_drc_lock;extern unsigned long nfsd_drc_max_mem;extern unsigned long nfsd_drc_mem_used; +extern atomic_t nfsd_th_cnt;/* number of available threads */ extern const struct seq_operations nfs_exports_op;
fs/nfsd/nfssvc.c +3 -2
@@ -34,6 +34,7 @@#define NFSDDBG_FACILITY NFSDDBG_SVC +atomic_t nfsd_th_cnt =ATOMIC_INIT (0 );extern struct svc_program nfsd_program;static int nfsd (void *vrqstp);#if defined(CONFIG_NFSD_V2_ACL ) || defined(CONFIG_NFSD_V3_ACL )
@@ -935,7 +936,7 @@ nfsd(void *vrqstp) current->fs->umask =0 ; -atomic_inc (&nfsdstats.th_cnt); +atomic_inc (&nfsd_th_cnt);set_freezable ();
@@ -959,7 +960,7 @@ nfsd(void *vrqstp)validate_process_creds (); } -atomic_dec (&nfsdstats.th_cnt); +atomic_dec (&nfsd_th_cnt); out:/* Release the thread */
fs/nfsd/stats.c +1 -2
@@ -27,7 +27,6 @@#include "nfsd.h" -struct nfsd_stats nfsdstats;struct svc_stat nfsd_svcstats = { .program = &nfsd_program, };
@@ -47,7 +46,7 @@ static int nfsd_show(struct seq_file *se percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE]));/* thread usage: */ -seq_printf (seq,"th %u 0" ,atomic_read (&nfsdstats.th_cnt)); +seq_printf (seq,"th %u 0" ,atomic_read (&nfsd_th_cnt));/* deprecated thread usage histogram stats */ for (i =0 ; i <10 ; i++)
fs/nfsd/stats.h +0 -6
@@ -10,12 +10,6 @@#include <uapi/linux/nfsd/stats.h> #include <linux/percpu_counter.h> -struct nfsd_stats { -atomic_t th_cnt;/* number of available threads */ -}; - -extern struct nfsd_stats nfsdstats; -extern struct svc_stat nfsd_svcstats;int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);
Greg Kroah-Hartman
maintainerPATCH 96/186 nfsd: make svc_stat per-network namespace instead of global
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 16fb9808ab2c99979f081987752abcbc5b092eac ]
The final bit of stats that is global is the rpc svc_stat. Move this into the nfsd_net struct and use that everywhere instead of the global struct. Remove the unused global struct.
--- fs/nfsd/netns.h | 4 ++++ fs/nfsd/nfsctl.c | 2 ++ fs/nfsd/nfssvc.c | 2 +- fs/nfsd/stats.c | 10 ++++------ fs/nfsd/stats.h | 2 -- 5 files changed, 11 insertions(+), 9 deletions(-)
fs/nfsd/netns.h +4 -0
@@ -13,6 +13,7 @@#include <linux/nfs4.h> #include <linux/percpu_counter.h> #include <linux/siphash.h> +#include <linux/sunrpc/stats.h> /* Hash tables for nfs4_clientid state */ #define CLIENT_HASH_BITS 4
@@ -183,6 +184,9 @@ struct nfsd_net {/* Per-netns stats counters */ struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM ]; +/* sunrpc svc stats */ +struct svc_stat nfsd_svcstats; +/* longest hash chain seen */ unsigned int longest_chain;
fs/nfsd/nfsctl.c +2 -0
@@ -1461,6 +1461,8 @@ static __net_init int nfsd_init_net(stru retval =nfsd_stat_counters_init (nn);if (retval) goto out_repcache_error; +memset (&nn->nfsd_svcstats,0 ,sizeof (nn->nfsd_svcstats)); + nn->nfsd_svcstats.program = &nfsd_program; nn->nfsd_versions =NULL ; nn->nfsd4_minorversions =NULL ;nfsd4_init_leases_net (nn);
fs/nfsd/nfssvc.c +1 -1
@@ -664,7 +664,7 @@ int nfsd_create_serv(struct net *net)if (nfsd_max_blksize ==0 ) nfsd_max_blksize =nfsd_get_default_max_blksize ();nfsd_reset_versions (nn); - serv =svc_create_pooled (&nfsd_program, &nfsd_svcstats, + serv =svc_create_pooled (&nfsd_program, &nn->nfsd_svcstats, nfsd_max_blksize, nfsd);if (serv ==NULL )return -ENOMEM ;
fs/nfsd/stats.c +4 -6
@@ -27,10 +27,6 @@#include "nfsd.h" -struct svc_stat nfsd_svcstats = { - .program = &nfsd_program, -}; -static int nfsd_show (struct seq_file *seq,void *v) {struct net *net =PDE_DATA (file_inode (seq->file));
@@ -56,7 +52,7 @@ static int nfsd_show(struct seq_file *seseq_puts (seq,"\nra 0 0 0 0 0 0 0 0 0 0 0 0\n" );/* show my rpc info */ -svc_seq_show (seq, &nfsd_svcstats); +svc_seq_show (seq, &nn->nfsd_svcstats);#ifdef CONFIG_NFSD_V4 /* Show count for individual nfsv4 operations */
@@ -119,7 +115,9 @@ void nfsd_stat_counters_destroy(struct nvoid nfsd_proc_stat_init (struct net *net) { -svc_proc_register (net, &nfsd_svcstats, &nfsd_proc_ops); +struct nfsd_net *nn =net_generic (net, nfsd_net_id); + +svc_proc_register (net, &nn->nfsd_svcstats, &nfsd_proc_ops); }void nfsd_proc_stat_shutdown (struct net *net)
fs/nfsd/stats.h +0 -2
@@ -10,8 +10,6 @@#include <uapi/linux/nfsd/stats.h> #include <linux/percpu_counter.h> -extern struct svc_stat nfsd_svcstats; -int nfsd_percpu_counters_init (struct percpu_counter *counters,int num);void nfsd_percpu_counters_reset (struct percpu_counter *counters,int num);void nfsd_percpu_counters_destroy (struct percpu_counter *counters,int num);
Greg Kroah-Hartman
maintainerPATCH 97/186 ALSA: hda: Add input value sanity checks to HDMI channel map controls
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
[ Upstream commit 6278056e42d953e207e2afd416be39d09ed2d496 ]
Add a simple sanity check to HD-audio HDMI Channel Map controls. Although the value might not be accepted for the actual connection, we can filter out some bogus values beforehand, and that should be enough for making kselftest happier.
--- sound/hda/hdmi_chmap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
sound/hda/hdmi_chmap.c +18 -0
@@ -753,6 +753,20 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,return 0 ; } +/* a simple sanity check for input values to chmap kcontrol */ +static int chmap_value_check (struct hdac_chmap *hchmap, +const struct snd_ctl_elem_value *ucontrol) +{ +int i; + +for (i =0 ; i < hchmap->channels_max; i++) { +if (ucontrol->value.integer.value[i] <0 || + ucontrol->value.integer.value[i] >SNDRV_CHMAP_LAST ) +return -EINVAL ; + } +return 0 ; +} +static int hdmi_chmap_ctl_put (struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) {
@@ -764,6 +778,10 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,unsigned char chmap[8 ], per_pin_chmap[8 ];int i, err, ca, prepared =0 ; + err =chmap_value_check (hchmap, ucontrol); +if (err <0 ) +return err; +/* No monitor is connected in dyn_pcm_assign. * It's invalid to setup the chmap */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 98/186 smack: unix sockets: fix accept()ed socket label
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Andreev <[email protected]>
[ Upstream commit e86cac0acdb1a74f608bacefe702f2034133a047 ]
When a process accept()s connection from a unix socket (either stream or seqpacket)
it gets the socket with the label of the connecting process.
For example, if a connecting process has a label 'foo', the accept()ed socket will also have 'in' and 'out' labels 'foo', regardless of the label of the listener process.
This is because kernel creates unix child sockets
in the context of the connecting process.
I do not see any obvious way for the listener to abuse alien labels coming with the new socket, but,
to be on the safe side, it's better fix new socket labels.
--- security/smack/smack_lsm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
security/smack/smack_lsm.c +9 -3
@@ -3642,12 +3642,18 @@ static int smack_unix_stream_connect(struct sock *sock, } } -/* -* Cross reference the peer labels for SO_PEERSEC. -*/ if (rc ==0 ) { +/* +* Cross reference the peer labels for SO_PEERSEC. +*/ nsp->smk_packet = ssp->smk_out; ssp->smk_packet = osp->smk_out; + +/* +* new/child/established socket must inherit listening socket labels +*/ + nsp->smk_out = osp->smk_out; + nsp->smk_in = osp->smk_in; }return rc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 99/186 irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár <[email protected]>
[ Upstream commit 3cef738208e5c3cb7084e208caf9bbf684f24feb ]
IRQs 0 (IPI) and 1 (MSI) are handled internally by this driver, generic_handle_domain_irq() is never called for these IRQs.
Disallow mapping these IRQs.
[ Marek: changed commit message ]
--- drivers/irqchip/irq-armada-370-xp.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/irqchip/irq-armada-370-xp.c +4 -0
@@ -546,6 +546,10 @@ static struct irq_chip armada_370_xp_irq_chip = {static int armada_370_xp_mpic_irq_map (struct irq_domain *h,unsigned int virq,irq_hw_number_t hw) { +/* IRQs 0 and 1 cannot be mapped, they are handled internally */ +if (hw <=1 ) +return -EINVAL ; +armada_370_xp_irq_mask (irq_get_irq_data (virq));if (!is_percpu_irq (hw)) writel(hw, per_cpu_int_base +
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 100/186 af_unix: Remove put_pid()/put_cred() in copy_peercred().
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e4bd881d987121dbf1a288641491955a53d9f8f7 ]
When (AF_UNIX, SOCK_STREAM) socket connect()s to a listening socket, the listener's sk_peer_pid/sk_peer_cred are copied to the client in copy_peercred().
Then, the client's sk_peer_pid and sk_peer_cred are always NULL, so we need not call put_pid() and put_cred() there.
--- net/unix/af_unix.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
net/unix/af_unix.c +1 -8
@@ -603,9 +603,6 @@ static void init_peercred(struct sock *sk)static void copy_peercred (struct sock *sk,struct sock *peersk) { -const struct cred *old_cred; -struct pid *old_pid; -if (sk < peersk) {spin_lock (&sk->sk_peer_lock);spin_lock_nested (&peersk->sk_peer_lock,SINGLE_DEPTH_NESTING );
@@ -613,16 +610,12 @@ static void copy_peercred(struct sock *sk, struct sock *peersk)spin_lock (&peersk->sk_peer_lock);spin_lock_nested (&sk->sk_peer_lock,SINGLE_DEPTH_NESTING ); } - old_pid = sk->sk_peer_pid; - old_cred = sk->sk_peer_cred; + sk->sk_peer_pid =get_pid (peersk->sk_peer_pid); sk->sk_peer_cred =get_cred (peersk->sk_peer_cred);spin_unlock (&sk->sk_peer_lock);spin_unlock (&peersk->sk_peer_lock); - -put_pid (old_pid); -put_cred (old_cred); }static int unix_listen (struct socket *sock,int backlog)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 101/186 iommu: sun50i: clear bypass register
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jernej Skrabec <[email protected]>
[ Upstream commit 927c70c93d929f4c2dcaf72f51b31bb7d118a51a ]
The Allwinner H6 IOMMU has a bypass register, which allows to circumvent the page tables for each possible master. The reset value for this register is 0, which disables the bypass.
The Allwinner H616 IOMMU resets this register to 0x7f, which activates the bypass for all masters, which is not what we want.
Always clear this register to 0, to enforce the usage of page tables, and make this driver compatible with the H616 in this respect.
--- drivers/iommu/sun50i-iommu.c | 1 + 1 file changed, 1 insertion(+)
drivers/iommu/sun50i-iommu.c +1 -0
@@ -380,6 +380,7 @@ static int sun50i_iommu_enable(struct sun50i_iommu *iommu)IOMMU_TLB_PREFETCH_MASTER_ENABLE (3 ) |IOMMU_TLB_PREFETCH_MASTER_ENABLE (4 ) | IOMMU_TLB_PREFETCH_MASTER_ENABLE(5)); +iommu_write (iommu,IOMMU_BYPASS_REG ,0 );iommu_write (iommu,IOMMU_INT_ENABLE_REG ,IOMMU_INT_MASK ); iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE), IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 102/186 netfilter: nf_conncount: fix wrong variable type
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunjian Wang <[email protected]>
[ Upstream commit 0b88d1654d556264bcd24a9cb6383f0888e30131 ]
Now there is a issue is that code checks reports a warning: implicit narrowing conversion from type 'unsigned int' to small type 'u8' (the 'keylen' variable). Fix it by removing the 'keylen' variable.
--- net/netfilter/nf_conncount.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/netfilter/nf_conncount.c +3 -5
@@ -310,7 +310,6 @@ insert_tree(struct net *net,struct nf_conncount_rb *rbconn;struct nf_conncount_tuple *conn;unsigned int count =0 , gc_count =0 ; -u8 keylen = data->keylen;bool do_gc = true;spin_lock_bh (&nf_conncount_locks[hash]);
@@ -322,7 +321,7 @@ insert_tree(struct net *net, rbconn = rb_entry(*rbnode, struct nf_conncount_rb, node); parent = *rbnode; - diff =key_diff (key, rbconn->key, keylen); + diff =key_diff (key, rbconn->key, data->keylen);if (diff <0 ) { rbnode = &((*rbnode)->rb_left); }else if (diff >0 ) {
@@ -367,7 +366,7 @@ insert_tree(struct net *net, conn->tuple = *tuple; conn->zone = *zone; -memcpy (rbconn->key, key,sizeof (u32) * keylen); +memcpy (rbconn->key, key,sizeof (u32) * data->keylen);nf_conncount_list_init (&rbconn->list);list_add (&conn->node, &rbconn->list.head);
@@ -392,7 +391,6 @@ count_tree(struct net *net,struct rb_node *parent;struct nf_conncount_rb *rbconn;unsigned int hash; -u8 keylen = data->keylen; hash =jhash2 (key, data->keylen, conncount_rnd) %CONNCOUNT_SLOTS ; root = &data->root[hash];
@@ -403,7 +401,7 @@ count_tree(struct net *net, rbconn = rb_entry(parent, struct nf_conncount_rb, node); - diff =key_diff (key, rbconn->key, keylen); + diff =key_diff (key, rbconn->key, data->keylen);if (diff <0 ) { parent =rcu_dereference_raw (parent->rb_left); }else if (diff >0 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 103/186 udf: Avoid excessive partition lengths
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
[ Upstream commit ebbe26fd54a9621994bc16b14f2ba8f84c089693 ]
Avoid mounting filesystems where the partition would overflow the 32-bits used for block number. Also refuse to mount filesystems where the partition length is so large we cannot safely index bits in a block bitmap.
--- fs/udf/super.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
fs/udf/super.c +15 -0
@@ -1083,12 +1083,19 @@ static int udf_fill_partdesc_info(struct super_block *sb,struct udf_part_map *map;struct udf_sb_info *sbi =UDF_SB (sb);struct partitionHeaderDesc *phd; +u32 sum;int err; map = &sbi->s_partmaps[p_index]; map->s_partition_len =le32_to_cpu (p->partitionLength);/* blocks */ map->s_partition_root =le32_to_cpu (p->partitionStartingLocation); +if (check_add_overflow (map->s_partition_root, map->s_partition_len, + &sum)) { +udf_err (sb,"Partition %d has invalid location %u + %u\n" , + p_index, map->s_partition_root, map->s_partition_len); +return -EFSCORRUPTED ; + }if (p->accessType ==cpu_to_le32 (PD_ACCESS_TYPE_READ_ONLY )) map->s_partition_flags |=UDF_PART_FLAG_READ_ONLY ;
@@ -1144,6 +1151,14 @@ static int udf_fill_partdesc_info(struct super_block *sb, bitmap->s_extPosition =le32_to_cpu ( phd->unallocSpaceBitmap.extPosition); map->s_partition_flags |=UDF_PART_FLAG_UNALLOC_BITMAP ; +/* Check whether math over bitmap won't overflow. */ +if (check_add_overflow (map->s_partition_len, +sizeof (struct spaceBitmapDesc ) <<3 , + &sum)) { +udf_err (sb,"Partition %d is too long (%u)\n" , p_index, + map->s_partition_len); +return -EFSCORRUPTED ; + }udf_debug ("unallocSpaceBitmap (part %d) @ %u\n" , p_index, bitmap->s_extPosition); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 104/186 media: vivid: fix wrong sizeimage value for mplane
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
[ Upstream commit 0fd7c0c2c156270dceb8c15fad3120cdce03e539 ]
In several places a division by fmt->vdownsampling[p] was missing in the sizeimage[p] calculation, causing incorrect behavior for multiplanar formats were some planes are smaller than the first plane.
Found by new v4l2-compliance tests.
--- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 5 +++-- drivers/media/test-drivers/vivid/vivid-vid-out.c | 16 +++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-)
drivers/media/test-drivers/vivid/vivid-vid-cap.c +3 -2
@@ -113,8 +113,9 @@ static int vid_cap_queue_setup(struct vb2_queue *vq,if (*nplanes != buffers)return -EINVAL ;for (p =0 ; p < buffers; p++) { -if (sizes[p] <tpg_g_line_width (&dev->tpg, p) * h + - dev->fmt_cap->data_offset[p]) +if (sizes[p] <tpg_g_line_width (&dev->tpg, p) * h / + dev->fmt_cap->vdownsampling[p] + + dev->fmt_cap->data_offset[p])return -EINVAL ; } }else {
drivers/media/test-drivers/vivid/vivid-vid-out.c +9 -7
@@ -63,14 +63,16 @@ static int vid_out_queue_setup(struct vb2_queue *vq,if (sizes[0 ] < size)return -EINVAL ;for (p =1 ; p < planes; p++) { -if (sizes[p] < dev->bytesperline_out[p] * h + - vfmt->data_offset[p]) +if (sizes[p] < dev->bytesperline_out[p] * h / + vfmt->vdownsampling[p] + + vfmt->data_offset[p])return -EINVAL ; } }else {for (p =0 ; p < planes; p++) - sizes[p] = p ? dev->bytesperline_out[p] * h + - vfmt->data_offset[p] : size; + sizes[p] = p ? dev->bytesperline_out[p] * h / + vfmt->vdownsampling[p] + + vfmt->data_offset[p] : size; }if (vq->num_buffers + *nbuffers <2 )
@@ -127,7 +129,7 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)for (p =0 ; p < planes; p++) {if (p) - size = dev->bytesperline_out[p] * h; + size = dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; size += vb->planes[p].data_offset;if (vb2_get_plane_payload (vb, p) < size) {
@@ -334,8 +336,8 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv,for (p =0 ; p < mp->num_planes; p++) { mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; mp->plane_fmt[p].sizeimage = - mp->plane_fmt[p].bytesperline * mp->height + - fmt->data_offset[p]; + mp->plane_fmt[p].bytesperline * mp->height / + fmt->vdownsampling[p] + fmt->data_offset[p]; }for (p = fmt->buffers; p < fmt->planes; p++) {unsigned stride = dev->bytesperline_out[p];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 105/186 leds: spi-byte: Call of_node_put() on error path
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 7f9ab862e05c5bc755f65bf6db7edcffb3b49dfc ]
Add a missing call to of_node_put(np) on error.
--- drivers/leds/leds-spi-byte.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/leds/leds-spi-byte.c +5 -1
@@ -91,7 +91,6 @@ static int spi_byte_probe(struct spi_device *spi)dev_err (dev,"Device must have exactly one LED sub-node." );return -EINVAL ; } - child =of_get_next_available_child (dev_of_node (dev),NULL ); led =devm_kzalloc (dev,sizeof (*led),GFP_KERNEL );if (!led)
@@ -107,11 +106,13 @@ static int spi_byte_probe(struct spi_device *spi) led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value; led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking; + child =of_get_next_available_child (dev_of_node (dev),NULL ); state =of_get_property (child,"default-state" ,NULL );if (state) {if (!strcmp (state,"on" )) { led->ldev.brightness = led->ldev.max_brightness; }else if (strcmp (state,"off" )) { +of_node_put (child);/* all other cases except "off" */ dev_err (dev,"default-state can only be 'on' or 'off'" );return -EINVAL ;
@@ -122,9 +123,12 @@ static int spi_byte_probe(struct spi_device *spi) ret =devm_led_classdev_register (&spi->dev, &led->ldev);if (ret) { +of_node_put (child);mutex_destroy (&led->mutex);return ret; } + +of_node_put (child);spi_set_drvdata (spi, led);return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 106/186 wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arend van Spriel <[email protected]>
[ Upstream commit dbb5265a5d7cca1cdba7736dba313ab7d07bc19d ]
After being asked about support for WPA3 for BCM43224 chipset it was found that all it takes is setting the MFP_CAPABLE flag and mac80211 will take care of all that is needed [1].
--- drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +1 -0
@@ -1089,6 +1089,7 @@ static int ieee_hw_init(struct ieee80211_hw *hw)ieee80211_hw_set (hw,AMPDU_AGGREGATION );ieee80211_hw_set (hw,SIGNAL_DBM );ieee80211_hw_set (hw,REPORTS_TX_ACK_STATUS ); +ieee80211_hw_set (hw,MFP_CAPABLE ); hw->extra_tx_headroom =brcms_c_get_header_len (); hw->queues =N_TX_QUEUES ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 107/186 usb: uas: set host status byte on data completion error
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shantanu Goel <[email protected]>
[ Upstream commit 9d32685a251a754f1823d287df233716aa23bcb9 ]
Set the host status byte when a data completion error is encountered otherwise the upper layer may end up using the invalid zero'ed data. The following output was observed from scsi/sd.c prior to this fix.
[ 11.872824] sd 0:0:0:1: [sdf] tag#9 data cmplt err -75 uas-tag 1 inflight: [ 11.872826] sd 0:0:0:1: [sdf] tag#9 CDB: Read capacity(16) 9e 10 00 00 00 00 00 00 00 00 00 00 00 20 00 00 [ 11.872830] sd 0:0:0:1: [sdf] Sector size 0 reported, assuming 512.
--- drivers/usb/storage/uas.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/storage/uas.c +1 -0
@@ -424,6 +424,7 @@ static void uas_data_cmplt(struct urb *urb)uas_log_cmd_state (cmnd,"data cmplt err" , status);/* error: no data transfered */ scsi_set_resid (cmnd, sdb->length); +set_host_byte (cmnd,DID_ERROR ); }else {scsi_set_resid (cmnd, sdb->length - urb->actual_length); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 108/186 media: vivid: dont set HDMI TX controls if there are no HDMI outputs
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Verkuil <[email protected]>
[ Upstream commit 17763960b1784578e8fe915304b330922f646209 ]
When setting the EDID it would attempt to update two controls that are only present if there is an HDMI output configured.
If there isn't any (e.g. when the vivid module is loaded with node_types=1), then calling VIDIOC_S_EDID would crash.
Fix this by first checking if outputs are present.
--- drivers/media/test-drivers/vivid/vivid-vid-cap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/media/test-drivers/vivid/vivid-vid-cap.c +8 -4
@@ -1802,8 +1802,10 @@ int vidioc_s_edid(struct file *file, void *_fh,return -EINVAL ;if (edid->blocks ==0 ) { dev->edid_blocks =0 ; -v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present,0 ); -v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug,0 ); +if (dev->num_outputs) { +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present,0 ); +v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug,0 ); + } phys_addr =CEC_PHYS_ADDR_INVALID ; goto set_phys_addr; }
@@ -1827,8 +1829,10 @@ int vidioc_s_edid(struct file *file, void *_fh, display_present |= dev->display_present[i] << j++; -v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present); -v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present); +if (dev->num_outputs) { +v4l2_ctrl_s_ctrl (dev->ctrl_tx_edid_present, display_present); +v4l2_ctrl_s_ctrl (dev->ctrl_tx_hotplug, display_present); + } set_phys_addr:/* TODO: a proper hotplug detect cycle should be emulated here */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 109/186 PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kishon Vijay Abraham I <[email protected]>
[ Upstream commit 86f271f22bbb6391410a07e08d6ca3757fda01fa ]
Errata #i2037 in AM65x/DRA80xM Processors Silicon Revision 1.0 (SPRZ452D_July 2018_Revised December 2019 [1]) mentions when an inbound PCIe TLP spans more than two internal AXI 128-byte bursts, the bus may corrupt the packet payload and the corrupt data may cause associated applications or the processor to hang.
The workaround for Errata #i2037 is to limit the maximum read request size and maximum payload size to 128 bytes. Add workaround for Errata #i2037 here.
The errata and workaround is applicable only to AM65x SR 1.0 and later versions of the silicon will have this fixed.
[1] -> https://www.ti.com/lit/er/sprz452i/sprz452i.pdf
--- drivers/pci/controller/dwc/pci-keystone.c | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +43 -1
@@ -35,6 +35,11 @@#define PCIE_DEVICEID_SHIFT 16/* Application registers */ +#define PID 0x000 +#define RTL GENMASK(15, 11) +#define RTL_SHIFT 11 +#define AM6_PCI_PG1_RTL_VER 0x15 +#define CMD_STATUS 0x004#define LTSSM_EN_VAL BIT(0)#define OB_XLAT_EN_VAL BIT(1)
@@ -105,6 +110,8 @@#define to_keystone_pcie (x) dev_get_drvdata((x)->dev) +#define PCI_DEVICE_ID_TI_AM654X 0xb00c +struct ks_pcie_of_data {enum dw_pcie_device_mode mode;const struct dw_pcie_host_ops *host_ops;
@@ -537,7 +544,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci)static void ks_pcie_quirk (struct pci_dev *dev) {struct pci_bus *bus = dev->bus; +struct keystone_pcie *ks_pcie; +struct device *bridge_dev;struct pci_dev *bridge; +u32 val; +static const struct pci_device_id rc_pci_devids[] = { {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCIE_RC_K2HK ), .class =PCI_CLASS_BRIDGE_PCI <<8 , .class_mask = ~0 , },
@@ -549,6 +560,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, { 0, }, }; +static const struct pci_device_id am6_pci_devids[] = { + {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCI_DEVICE_ID_TI_AM654X ), + .class =PCI_CLASS_BRIDGE_PCI <<8 , .class_mask = ~0 , }, + {0 , }, + };if (pci_is_root_bus (bus)) bridge = dev;
@@ -570,10 +586,36 @@ static void ks_pcie_quirk(struct pci_dev *dev)*/ if (pci_match_id (rc_pci_devids, bridge)) {if (pcie_get_readrq (dev) >256 ) { -dev_info (&dev->dev,"limiting MRRS to 256\n" ); +dev_info (&dev->dev,"limiting MRRS to 256 bytes\n" );pcie_set_readrq (dev,256 ); } } + +/* +* Memory transactions fail with PCI controller in AM654 PG1.0 +* when MRRS is set to more than 128 bytes. Force the MRRS to +* 128 bytes in all downstream devices. +*/ +if (pci_match_id (am6_pci_devids, bridge)) { + bridge_dev =pci_get_host_bridge_device (dev); +if (!bridge_dev && !bridge_dev->parent) +return ; + + ks_pcie =dev_get_drvdata (bridge_dev->parent); +if (!ks_pcie) +return ; + + val =ks_pcie_app_readl (ks_pcie,PID ); + val &=RTL ; + val >>=RTL_SHIFT ; +if (val !=AM6_PCI_PG1_RTL_VER ) +return ; + +if (pcie_get_readrq (dev) >128 ) { +dev_info (&dev->dev,"limiting MRRS to 128 bytes\n" ); +pcie_set_readrq (dev,128 ); + } + } }DECLARE_PCI_FIXUP_ENABLE (PCI_ANY_ID ,PCI_ANY_ID , ks_pcie_quirk);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 110/186 media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni <[email protected]>
[ Upstream commit 4caf6d93d9f2c11d6441c64e1c549c445fa322ed ]
Add check for the return value of v4l2_fwnode_endpoint_parse() and return the error if it fails in order to catch the error.
--- drivers/media/platform/qcom/camss/camss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss.c +4 -1
@@ -431,8 +431,11 @@ static int camss_of_parse_endpoint_node(struct device *dev,struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2;struct v4l2_fwnode_endpoint vep = { {0 } };unsigned int i; +int ret; -v4l2_fwnode_endpoint_parse (of_fwnode_handle (node), &vep); + ret =v4l2_fwnode_endpoint_parse (of_fwnode_handle (node), &vep); +if (ret) +return ret; csd->interface.csiphy_id = vep.base.port;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 111/186 pcmcia: Use resource_size function on resource object
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jules Irenge <[email protected]>
[ Upstream commit 24a025497e7e883bd2adef5d0ece1e9b9268009f ]
Cocinnele reports a warning
WARNING: Suspicious code. resource_size is maybe missing with root
The root cause is the function resource_size is not used when needed
Use resource_size() on variable "root" of type resource
--- drivers/pcmcia/yenta_socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pcmcia/yenta_socket.c +3 -3
@@ -636,11 +636,11 @@ static int yenta_search_one_res(struct resource *root, struct resource *res, start =PCIBIOS_MIN_CARDBUS_IO ; end = ~0U ; }else { -unsigned long avail = root->end - root->start; +unsigned long avail =resource_size (root);int i; size =BRIDGE_MEM_MAX ; -if (size > avail/8 ) { - size = (avail+1 )/8 ; +if (size > (avail -1 ) /8 ) { + size = avail /8 ;/* round size down to next power of 2 */ i =0 ;while ((size /=2 ) !=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 112/186 can: bcm: Remove proc entry when dev is unregistered.
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 76fe372ccb81b0c89b6cd2fec26e2f38c958be85 ]
syzkaller reported a warning in bcm_connect() below. [0]
The repro calls connect() to vxcan1, removes vxcan1, and calls connect() with ifindex == 0.
Calling connect() for a BCM socket allocates a proc entry. Then, bcm_sk(sk)->bound is set to 1 to prevent further connect().
However, removing the bound device resets bcm_sk(sk)->bound to 0 in bcm_notify().
The 2nd connect() tries to allocate a proc entry with the same name and sets NULL to bcm_sk(sk)->bcm_proc_read, leaking the original proc entry.
Since the proc entry is available only for connect()ed sockets, let's clean up the entry when the bound netdev is unregistered.
[0]:proc_dir_entry 'can-bcm/2456' already registered
WARNING: CPU: 1 PID: 394 at fs/proc/generic.c:376 proc_register+0x645/0x8f0 fs/proc/generic.c:375 Modules linked in: CPU: 1 PID: 394 Comm: syz-executor403 Not tainted 6.10.0-rc7-g852e42cc2dd4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:proc_register+0x645/0x8f0 fs/proc/generic.c:375 Code: 00 00 00 00 00 48 85 ed 0f 85 97 02 00 00 4d 85 f6 0f 85 9f 02 00 00 48 c7 c7 9b cb cf 87 48 89 de 4c 89 fa e8 1c 6f eb fe 90 <0f> 0b 90 90 48 c7 c7 98 37 99 89 e8 cb 7e 22 05 bb 00 00 00 10 48 RSP: 0018:ffa0000000cd7c30 EFLAGS: 00010246 RAX: 9e129be1950f0200 RBX: ff1100011b51582c RCX: ff1100011857cd80 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002 RBP: 0000000000000000 R08: ffd400000000000f R09: ff1100013e78cac0 R10: ffac800000cd7980 R11: ff1100013e12b1f0 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: ff1100011a99a2ec FS: 00007fbd7086f740(0000) GS:ff1100013fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000200071c0 CR3: 0000000118556004 CR4: 0000000000771ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> proc_create_net_single+0x144/0x210 fs/proc/proc_net.c:220 bcm_connect+0x472/0x840 net/can/bcm.c:1673 __sys_connect_file net/socket.c:2049 [inline] __sys_connect+0x5d2/0x690 net/socket.c:2066 __do_sys_connect net/socket.c:2076 [inline] __se_sys_connect net/socket.c:2073 [inline] __x64_sys_connect+0x8f/0x100 net/socket.c:2073 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xd9/0x1c0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7fbd708b0e5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007fff8cd33f08 EFLAGS: 00000246 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fbd708b0e5d RDX: 0000000000000010 RSI: 0000000020000040 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000000000040 R09: 0000000000000040 R10: 0000000000000040 R11: 0000000000000246 R12: 00007fff8cd34098 R13: 0000000000401280 R14: 0000000000406de8 R15: 00007fbd70ab9000 </TASK>
remove_proc_entry: removing non-empty directory 'net/can-bcm', leaking at least '2456'
--- net/can/bcm.c | 4 ++++ 1 file changed, 4 insertions(+)
net/can/bcm.c +4 -0
@@ -1423,6 +1423,10 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,/* remove device reference, if this is our bound device */ if (bo->bound && bo->ifindex == dev->ifindex) { +#if IS_ENABLED (CONFIG_PROC_FS ) +if (sock_net (sk)->can.bcmproc_dir && bo->bcm_proc_read) +remove_proc_entry (bo->procname,sock_net (sk)->can.bcmproc_dir); +#endif bo->bound =0 ; bo->ifindex =0 ; notify_enodev =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 113/186 igb: Fix not clearing TimeSync interrupts for 82580
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daiwei Li <[email protected]>
[ Upstream commit ba8cf80724dbc09825b52498e4efacb563935408 ]
82580 NICs have a hardware bug that makes it
necessary to write into the TSICR (TimeSync Interrupt Cause) register to clear it:
https://lore.kernel.org/all/CDCB8BE0.1EC2C%[email protected]/
Add a conditional so only for 82580 we write into the TSICR register, so we don't risk losing events for other models.
Without this change, when running ptp4l with an Intel 82580 card, I get the following output:
Quoted 3 lines
timed out while polling for tx timestamp increasing
tx_timestamp_timeoutor increasing kworker priority may correct this issue, but a driver bug likely causes it
This goes away with this change.
This (partially) reverts commit ee14cc9ea19b ("igb: Fix missing time sync events").
--- drivers/net/ethernet/intel/igb/igb_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/intel/igb/igb_main.c +10 -0
@@ -6805,10 +6805,20 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)static void igb_tsync_interrupt (struct igb_adapter *adapter) { +const u32 mask = (TSINTR_SYS_WRAP |E1000_TSICR_TXTS | +TSINTR_TT0 |TSINTR_TT1 | +TSINTR_AUTT0 |TSINTR_AUTT1 );struct e1000_hw *hw = &adapter->hw;u32 tsicr =rd32 (E1000_TSICR );struct ptp_clock_event event; +if (hw->mac.type == e1000_82580) { +/* 82580 has a hardware bug that requires an explicit +* write to clear the TimeSync interrupt cause. +*/ +wr32 (E1000_TSICR , tsicr & mask); + } +if (tsicr &TSINTR_SYS_WRAP ) { event.type =PTP_CLOCK_PPS ;if (adapter->ptp_caps.pps)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 114/186 svcrdma: Catch another Reply chunk overflow case
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <[email protected]>
[ Upstream commit e5decb2eb5f4d1f64ba9196b4bad0e26a441c81c ]
When space in the Reply chunk runs out in the middle of a segment, we end up passing a zero-length SGL to rdma_rw_ctx_init(), and it oopses.
Stable-dep-of: ffc17e1479e8 ("platform/x86: dell-smbios: Fix error path in dell_smbios_init()")
--- net/sunrpc/xprtrdma/svc_rdma_rw.c | 2 ++ 1 file changed, 2 insertions(+)
net/sunrpc/xprtrdma/svc_rdma_rw.c +2 -0
@@ -460,6 +460,8 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info, offset += info->wi_seg_off; write_len =min (remaining, length - info->wi_seg_off); +if (!write_len) + goto out_overflow; ctxt =svc_rdma_get_rw_ctxt (rdma, (write_len >>PAGE_SHIFT ) +2 );if (!ctxt)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 115/186 platform/x86: dell-smbios: Fix error path in dell_smbios_init()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <[email protected]>
[ Upstream commit ffc17e1479e8e9459b7afa80e5d9d40d0dd78abb ]
In case of error in build_tokens_sysfs(), all the memory that has been allocated is freed at end of this function. But then free_group() is called which performs memory deallocation again.
Also, instead of free_group() call, there should be exit_dell_smbios_smm() and exit_dell_smbios_wmi() calls, since there is initialization, but there is no release of resources in case of an error.
Fix these issues by replacing free_group() call with exit_dell_smbios_wmi() and exit_dell_smbios_smm().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/platform/x86/dell-smbios-base.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/platform/x86/dell-smbios-base.c +4 -1
@@ -610,7 +610,10 @@ static int __init dell_smbios_init(void)return 0 ; fail_sysfs: -free_group (platform_device); +if (!wmi) +exit_dell_smbios_wmi (); +if (!smm) +exit_dell_smbios_smm (); fail_create_group:platform_device_del (platform_device);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 116/186 tcp_bpf: fix return value of tcp_bpf_sendmsg()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
[ Upstream commit fe1910f9337bd46a9343967b547ccab26b4b2c6e ]
When we cork messages in psock->cork, the last message triggers the flushing will result in sending a sk_msg larger than the current message size. In this case, in tcp_bpf_send_verdict(), 'copied' becomes negative at least in the following case:
468 case __SK_DROP:
469 default:
470 sk_msg_free_partial(sk, msg, tosend); 471 sk_msg_apply_bytes(psock, tosend); 472 *copied -= (tosend + delta); // <==== HERE 473 return -EACCES;
Therefore, it could lead to the following BUG with a proper value of 'copied' (thanks to syzbot). We should not use negative 'copied' as a return value here.
------------[ cut here ]------------ kernel BUG at net/socket.c:733! Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP Modules linked in: CPU: 0 UID: 0 PID: 3265 Comm: syz-executor510 Not tainted 6.11.0-rc3-syzkaller-00060-gd07b43284ab3 #0 Hardware name: linux,dummy-virt (DT) pstate: 61400009 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) pc : sock_sendmsg_nosec net/socket.c:733 [inline] pc : sock_sendmsg_nosec net/socket.c:728 [inline] pc : __sock_sendmsg+0x5c/0x60 net/socket.c:745 lr : sock_sendmsg_nosec net/socket.c:730 [inline] lr : __sock_sendmsg+0x54/0x60 net/socket.c:745 sp : ffff800088ea3b30 x29: ffff800088ea3b30 x28: fbf00000062bc900 x27: 0000000000000000 x26: ffff800088ea3bc0 x25: ffff800088ea3bc0 x24: 0000000000000000 x23: f9f00000048dc000 x22: 0000000000000000 x21: ffff800088ea3d90 x20: f9f00000048dc000 x19: ffff800088ea3d90 x18: 0000000000000001 x17: 0000000000000000 x16: 0000000000000000 x15: 000000002002ffaf x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 x11: 0000000000000000 x10: ffff8000815849c0 x9 : ffff8000815b49c0 x8 : 0000000000000000 x7 : 000000000000003f x6 : 0000000000000000 x5 : 00000000000007e0 x4 : fff07ffffd239000 x3 : fbf00000062bc900 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 00000000fffffdef Call trace: sock_sendmsg_nosec net/socket.c:733 [inline] __sock_sendmsg+0x5c/0x60 net/socket.c:745 ____sys_sendmsg+0x274/0x2ac net/socket.c:2597 ___sys_sendmsg+0xac/0x100 net/socket.c:2651 __sys_sendmsg+0x84/0xe0 net/socket.c:2680 __do_sys_sendmsg net/socket.c:2689 [inline] __se_sys_sendmsg net/socket.c:2687 [inline] __arm64_sys_sendmsg+0x24/0x30 net/socket.c:2687 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x48/0x110 arch/arm64/kernel/syscall.c:49 el0_svc_common.constprop.0+0x40/0xe0 arch/arm64/kernel/syscall.c:132 do_el0_svc+0x1c/0x28 arch/arm64/kernel/syscall.c:151 el0_svc+0x34/0xec arch/arm64/kernel/entry-common.c:712 el0t_64_sync_handler+0x100/0x12c arch/arm64/kernel/entry-common.c:730 el0t_64_sync+0x19c/0x1a0 arch/arm64/kernel/entry.S:598 Code: f9404463 d63f0060 3108441f 54fffe81 (d4210000) ---[ end trace 0000000000000000 ]---
--- net/ipv4/tcp_bpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp_bpf.c +1 -1
@@ -511,7 +511,7 @@ static int tcp_bpf_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) err =sk_stream_error (sk, msg->msg_flags, err);release_sock (sk);sk_psock_put (sk, psock); -return copied ? copied : err; +return copied >0 ? copied : err; } static int tcp_bpf_sendpage(struct sock *sk, struct page *page, int offset,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 117/186 igc: Unlock on error in igc_io_resume()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit ef4a99a0164e3972abb421cbb1b09ea6c61414df ]
Call rtnl_unlock() on this error path, before returning.
--- drivers/net/ethernet/intel/igc/igc_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/igc/igc_main.c +1 -0
@@ -5740,6 +5740,7 @@ static void igc_io_resume(struct pci_dev *pdev)rtnl_lock ();if (netif_running (netdev)) {if (igc_open (netdev)) { +rtnl_unlock ();netdev_err (netdev,"igc_open failed after reset\n" );return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 118/186 drivers/net/usb: Remove all strcpy() uses
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Len Baker <[email protected]>
[ Upstream commit 493c3ca6bd754d8587604496eb814f72e933075d ]
strcpy() performs no bounds checking on the destination buffer. This could result in linear overflows beyond the end of the buffer, leading to all kinds of misbehaviors. The safe replacement is strscpy().
Stable-dep-of: bab8eb0dd4cb ("usbnet: modern method to get random MAC")
--- drivers/net/usb/ipheth.c | 2 +- drivers/net/usb/usbnet.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/net/usb/ipheth.c +1 -1
@@ -443,7 +443,7 @@ static int ipheth_probe(struct usb_interface *intf, netdev->netdev_ops = &ipheth_netdev_ops; netdev->watchdog_timeo =IPHETH_TX_TIMEOUT ; -strcpy (netdev->name,"eth%d" ); +strscpy (netdev->name,"eth%d" ,sizeof (netdev->name)); dev =netdev_priv (netdev); dev->udev = udev;
drivers/net/usb/usbnet.c +4 -4
@@ -1693,7 +1693,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->interrupt_count =0 ; dev->net = net; -strcpy (net->name,"usb%d" ); +strscpy (net->name,"usb%d" ,sizeof (net->name));memcpy (net->dev_addr, node_id,sizeof node_id);/* rx and tx sides can use different message sizes;
@@ -1720,13 +1720,13 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)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" ); +strscpy (net->name,"eth%d" ,sizeof (net->name));/* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags &FLAG_WLAN ) !=0 ) -strcpy (net->name,"wlan%d" ); +strscpy (net->name,"wlan%d" ,sizeof (net->name));/* WWAN devices should always be named "wwan%d" */ if ((dev->driver_info->flags &FLAG_WWAN ) !=0 ) -strcpy (net->name,"wwan%d" ); +strscpy (net->name,"wwan%d" ,sizeof (net->name));/* devices that cannot do ARP */ if ((dev->driver_info->flags &FLAG_NOARP ) !=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 119/186 net: usb: dont write directly to netdev->dev_addr
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 2674e7ea22ba0e22a2d1603bd51e0b8f6442a267 ]
Commit 406f42fa0d3c ("net-next: When a bond have a massive amount of VLANs...") introduced a rbtree for faster Ethernet address look up. To maintain netdev->dev_addr in this tree we need to make all the writes to it got through appropriate helpers.
Manually fix all net/usb drivers without separate maintainers.
v2: catc does DMA to the buffer, leave the conversion to Oliver
Stable-dep-of: bab8eb0dd4cb ("usbnet: modern method to get random MAC")
--- drivers/net/usb/ch9200.c | 4 +++- drivers/net/usb/cx82310_eth.c | 5 +++-- drivers/net/usb/kaweth.c | 3 +-- drivers/net/usb/mcs7830.c | 4 +++- drivers/net/usb/sierra_net.c | 6 ++++-- drivers/net/usb/sr9700.c | 4 +++- drivers/net/usb/sr9800.c | 5 +++-- drivers/net/usb/usbnet.c | 6 ++++-- 8 files changed, 24 insertions(+), 13 deletions(-)
drivers/net/usb/ch9200.c +3 -1
@@ -336,6 +336,7 @@ static int ch9200_bind(struct usbnet *dev, struct usb_interface *intf) {int retval =0 ;unsigned char data[2 ]; +u8 addr[ETH_ALEN ]; retval =usbnet_get_endpoints (dev, intf);if (retval)
@@ -383,7 +384,8 @@ static int ch9200_bind(struct usbnet *dev, struct usb_interface *intf) retval =control_write (dev,REQUEST_WRITE ,0 ,MAC_REG_CTRL , data,0x02 ,CONTROL_TIMEOUT_MS ); - retval =get_mac_address (dev, dev->net->dev_addr); + retval =get_mac_address (dev, addr); +eth_hw_addr_set (dev->net, addr);return retval; }
drivers/net/usb/cx82310_eth.c +3 -2
@@ -146,6 +146,7 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)u8 link[3 ];int timeout =50 ;struct cx82310_priv *priv; +u8 addr[ETH_ALEN ];/* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
@@ -202,12 +203,12 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) goto err;/* get the MAC address */ - ret =cx82310_cmd (dev,CMD_GET_MAC_ADDR , true,NULL ,0 , - dev->net->dev_addr,ETH_ALEN ); + ret =cx82310_cmd (dev,CMD_GET_MAC_ADDR , true,NULL ,0 , addr,ETH_ALEN );if (ret) {netdev_err (dev->net,"unable to read MAC address: %d\n" , ret); goto err; } +eth_hw_addr_set (dev->net, addr);/* start (does not seem to have any effect?) */ ret =cx82310_cmd (dev,CMD_START , false,NULL ,0 ,NULL ,0 );
drivers/net/usb/kaweth.c +1 -2
@@ -1044,8 +1044,7 @@ static int kaweth_probe( goto err_all_but_rxbuf;memcpy (netdev->broadcast, &bcast_addr,sizeof (bcast_addr)); -memcpy (netdev->dev_addr, &kaweth->configuration.hw_addr, -sizeof (kaweth->configuration.hw_addr)); +eth_hw_addr_set (netdev, (u8 *)&kaweth->configuration.hw_addr); netdev->netdev_ops = &kaweth_netdev_ops; netdev->watchdog_timeo =KAWETH_TX_TIMEOUT ;
drivers/net/usb/mcs7830.c +3 -1
@@ -480,17 +480,19 @@ static const struct net_device_ops mcs7830_netdev_ops = {static int mcs7830_bind (struct usbnet *dev,struct usb_interface *udev) {struct net_device *net = dev->net; +u8 addr[ETH_ALEN ];int ret;int retry;/* Initial startup: Gather MAC address setting from EEPROM */ ret = -EINVAL ;for (retry =0 ; retry <5 && ret; retry++) - ret =mcs7830_hif_get_mac_address (dev, net->dev_addr); + ret =mcs7830_hif_get_mac_address (dev, addr);if (ret) {dev_warn (&dev->udev->dev,"Cannot read MAC address\n" ); goto out; } +eth_hw_addr_set (net, addr);mcs7830_data_set_multicast (net);
drivers/net/usb/sierra_net.c +4 -2
@@ -669,6 +669,7 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};static const u8 shdwn_tmplate[sizeof (priv->shdwn_msg)] = {0x00 ,0x00 ,SIERRA_NET_HIP_SHUTD_ID ,0x00 }; +u8 mod[2 ];dev_dbg (&dev->udev->dev,"%s" , __func__);
@@ -698,8 +699,9 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->netdev_ops = &sierra_net_device_ops;/* change MAC addr to include, ifacenum, and to be unique */ - dev->net->dev_addr[ETH_ALEN -2 ] =atomic_inc_return (&iface_counter); - dev->net->dev_addr[ETH_ALEN -1 ] = ifacenum; + mod[0 ] =atomic_inc_return (&iface_counter); + mod[1 ] = ifacenum; +dev_addr_mod (dev->net,ETH_ALEN -2 , mod,2 );/* prepare shutdown message template */ memcpy (priv->shdwn_msg, shdwn_tmplate,sizeof (priv->shdwn_msg));
drivers/net/usb/sr9700.c +3 -1
@@ -326,6 +326,7 @@ static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) {struct net_device *netdev;struct mii_if_info *mii; +u8 addr[ETH_ALEN ];int ret; ret =usbnet_get_endpoints (dev, intf);
@@ -356,11 +357,12 @@ static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf)* EEPROM automatically to PAR. In case there is no EEPROM externally, * a default MAC address is stored in PAR for making chip work properly. */ -if (sr_read (dev,SR_PAR ,ETH_ALEN , netdev->dev_addr) <0 ) { +if (sr_read (dev,SR_PAR ,ETH_ALEN , addr) <0 ) {netdev_err (netdev,"Error reading MAC address\n" ); ret = -ENODEV ; goto out; } +eth_hw_addr_set (netdev, addr);/* power up and reset phy */ sr_write_reg (dev,SR_PRR ,PRR_PHY_RST );
drivers/net/usb/sr9800.c +3 -2
@@ -731,6 +731,7 @@ static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf)struct sr_data *data = (struct sr_data *)&dev->data;u16 led01_mux, led23_mux;int ret, embd_phy; +u8 addr[ETH_ALEN ];u32 phyid;u16 rx_ctl;
@@ -756,12 +757,12 @@ static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) }/* Get the MAC address */ - ret =sr_read_cmd (dev,SR_CMD_READ_NODE_ID ,0 ,0 ,ETH_ALEN , - dev->net->dev_addr); + ret =sr_read_cmd (dev,SR_CMD_READ_NODE_ID ,0 ,0 ,ETH_ALEN , addr);if (ret <0 ) {netdev_dbg (dev->net,"Failed to read MAC address: %d\n" , ret);return ret; } +eth_hw_addr_set (dev->net, addr);netdev_dbg (dev->net,"mac addr : %pM\n" , dev->net->dev_addr);/* Initialize MII structure */
drivers/net/usb/usbnet.c +4 -2
@@ -148,12 +148,13 @@ EXPORT_SYMBOL_GPL(usbnet_get_endpoints);int usbnet_get_ethernet_addr (struct usbnet *dev,int iMACAddress) { +u8 addr[ETH_ALEN ];int tmp =-1 , ret;unsigned char buf [13 ]; ret =usb_string (dev->udev, iMACAddress, buf,sizeof buf);if (ret ==12 ) - tmp =hex2bin (dev->net->dev_addr, buf,6 ); + tmp =hex2bin (addr, buf,6 );if (tmp <0 ) {dev_dbg (&dev->udev->dev,"bad MAC string %d fetch, %d\n" , iMACAddress, tmp);
@@ -161,6 +162,7 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) ret = -EINVAL ;return ret; } +eth_hw_addr_set (dev->net, addr);return 0 ; }EXPORT_SYMBOL_GPL (usbnet_get_ethernet_addr);
@@ -1694,7 +1696,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->net = net;strscpy (net->name,"usb%d" ,sizeof (net->name)); -memcpy (net->dev_addr, node_id,sizeof node_id); +eth_hw_addr_set (net, node_id);/* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 120/186 usbnet: modern method to get random MAC
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit bab8eb0dd4cb995caa4a0529d5655531c2ec5e8e ]
The driver generates a random MAC once on load and uses it over and over, including on two devices needing a random MAC at the same time.
Jakub suggested revamping the driver to the modern API for setting a random MAC rather than fixing the old stuff.
The bug is as old as the driver.
--- drivers/net/usb/usbnet.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/net/usb/usbnet.c +3 -8
@@ -64,9 +64,6 @@/*-------------------------------------------------------------------------*/ -// randomly generated ethernet address -static u8 node_id [ETH_ALEN ]; -/* use ethtool to change the level for any given device */ static int msg_level =-1 ;module_param (msg_level, int,0 );
@@ -1696,7 +1693,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->net = net;strscpy (net->name,"usb%d" ,sizeof (net->name)); -eth_hw_addr_set (net, node_id);/* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case.
@@ -1770,9 +1766,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) goto out4; } -/* let userspace know we have a random address */ -if (ether_addr_equal (net->dev_addr, node_id)) - net->addr_assign_type =NET_ADDR_RANDOM ; +/* this flags the device for user space */ +if (!is_valid_ether_addr (net->dev_addr)) +eth_hw_addr_random (net);if ((dev->driver_info->flags &FLAG_WLAN ) !=0 )SET_NETDEV_DEVTYPE (net, &wlan_type);
@@ -2182,7 +2178,6 @@ static int __init usbnet_init(void) BUILD_BUG_ON( sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data)); -eth_random_addr (node_id);return 0 ; }module_init (usbnet_init);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 121/186 bareudp: Fix device stats updates.
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 4963d2343af81f493519f9c3ea9f2169eaa7353a ]
Bareudp devices update their stats concurrently.
Therefore they need proper atomic increments.
--- drivers/net/bareudp.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/net/bareudp.c +11 -11
@@ -75,7 +75,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)if (skb_copy_bits (skb,BAREUDP_BASE_HLEN , &ipversion,sizeof (ipversion))) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } ipversion >>=4 ;
@@ -85,7 +85,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) }else if (ipversion ==6 && bareudp->multi_proto_mode) { proto =htons (ETH_P_IPV6 ); }else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }else if (bareudp->ethertype ==htons (ETH_P_MPLS_UC )) {
@@ -99,7 +99,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) ipv4_is_multicast(tunnel_hdr->daddr)) { proto = htons(ETH_P_MPLS_MC); } else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }else {
@@ -115,7 +115,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) (addr_type & IPV6_ADDR_MULTICAST)) { proto = htons(ETH_P_MPLS_MC); } else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }
@@ -127,12 +127,12 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) proto, !net_eq(bareudp->net, dev_net(bareudp->dev)))) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } tun_dst =udp_tun_rx_dst (skb, family,TUNNEL_KEY ,0 ,0 );if (!tun_dst) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; }skb_dst_set (skb, &tun_dst->dst);
@@ -157,8 +157,8 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) &((struct ipv6hdr *)oiph)->saddr); }if (err >1 ) { - ++bareudp->dev->stats.rx_frame_errors; - ++bareudp->dev->stats.rx_errors; +DEV_STATS_INC (bareudp->dev, rx_frame_errors); +DEV_STATS_INC (bareudp->dev, rx_errors); goto drop; } }
@@ -453,11 +453,11 @@ static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev)dev_kfree_skb (skb);if (err == -ELOOP ) - dev->stats.collisions++; +DEV_STATS_INC (dev, collisions);else if (err == -ENETUNREACH ) - dev->stats.tx_carrier_errors++; +DEV_STATS_INC (dev, tx_carrier_errors); - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);return NETDEV_TX_OK ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 122/186 fou: remove sparse errors
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 8d65cd8d25fa23951171094553901d69a88ccdff ]
We need to add __rcu qualifier to avoid these errors:
net/ipv4/fou.c:250:18: warning: incorrect type in assignment (different address spaces)net/ipv4/fou.c:250:18: expected struct net_offload const **offloadsnet/ipv4/fou.c:250:18: got struct net_offload const [noderef] __rcu **net/ipv4/fou.c:251:15: error: incompatible types in comparison expression (different address spaces):net/ipv4/fou.c:251:15: struct net_offload const [noderef] __rcu *net/ipv4/fou.c:251:15: struct net_offload const *net/ipv4/fou.c:272:18: warning: incorrect type in assignment (different address spaces)net/ipv4/fou.c:272:18: expected struct net_offload const **offloadsnet/ipv4/fou.c:272:18: got struct net_offload const [noderef] __rcu **net/ipv4/fou.c:273:15: error: incompatible types in comparison expression (different address spaces):net/ipv4/fou.c:273:15: struct net_offload const [noderef] __rcu *net/ipv4/fou.c:273:15: struct net_offload const *net/ipv4/fou.c:442:18: warning: incorrect type in assignment (different address spaces)net/ipv4/fou.c:442:18: expected struct net_offload const **offloadsnet/ipv4/fou.c:442:18: got struct net_offload const [noderef] __rcu **net/ipv4/fou.c:443:15: error: incompatible types in comparison expression (different address spaces):net/ipv4/fou.c:443:15: struct net_offload const [noderef] __rcu *net/ipv4/fou.c:443:15: struct net_offload const *net/ipv4/fou.c:489:18: warning: incorrect type in assignment (different address spaces)net/ipv4/fou.c:489:18: expected struct net_offload const **offloadsnet/ipv4/fou.c:489:18: got struct net_offload const [noderef] __rcu **net/ipv4/fou.c:490:15: error: incompatible types in comparison expression (different address spaces):net/ipv4/fou.c:490:15: struct net_offload const [noderef] __rcu *net/ipv4/fou.c:490:15: struct net_offload const *net/ipv4/udp_offload.c:170:26: warning: incorrect type in assignment (different address spaces)net/ipv4/udp_offload.c:170:26: expected struct net_offload const **offloadsnet/ipv4/udp_offload.c:170:26: got struct net_offload const [noderef] __rcu **net/ipv4/udp_offload.c:171:23: error: incompatible types in comparison expression (different address spaces):net/ipv4/udp_offload.c:171:23: struct net_offload const [noderef] __rcu *net/ipv4/udp_offload.c:171:23: struct net_offload const *
Stable-dep-of: 7e4196935069 ("fou: Fix null-ptr-deref in GRO.")
--- net/ipv4/fou.c | 10 +++++----- net/ipv4/udp_offload.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
net/ipv4/fou.c +5 -5
@@ -230,8 +230,8 @@ static struct sk_buff *fou_gro_receive(struct sock *sk,struct list_head *head, struct sk_buff *skb) { + const struct net_offload __rcu **offloads;u8 proto =fou_from_sock (sk)->protocol; -const struct net_offload **offloads;const struct net_offload *ops;struct sk_buff *pp =NULL ;
@@ -263,10 +263,10 @@ static struct sk_buff *fou_gro_receive(struct sock *sk,static int fou_gro_complete (struct sock *sk,struct sk_buff *skb,int nhoff) { -const struct net_offload *ops; +const struct net_offload __rcu **offloads;u8 proto =fou_from_sock (sk)->protocol; +const struct net_offload *ops;int err = -ENOSYS ; -const struct net_offload **offloads;rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads;
@@ -311,7 +311,7 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,struct list_head *head, struct sk_buff *skb) { - const struct net_offload **offloads; + const struct net_offload __rcu **offloads;const struct net_offload *ops;struct sk_buff *pp =NULL ;struct sk_buff *p;
@@ -457,8 +457,8 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,static int gue_gro_complete (struct sock *sk,struct sk_buff *skb,int nhoff) { -const struct net_offload **offloads;struct guehdr *guehdr = (struct guehdr *)(skb->data + nhoff); +const struct net_offload __rcu **offloads;const struct net_offload *ops;unsigned int guehlen =0 ;u8 proto;
net/ipv4/udp_offload.c +1 -1
@@ -149,8 +149,8 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, netdev_features_t features, bool is_ipv6) { +const struct net_offload __rcu **offloads;__be16 protocol = skb->protocol; -const struct net_offload **offloads;const struct net_offload *ops;struct sk_buff *segs =ERR_PTR (-EINVAL ); struct sk_buff *(*gso_inner_segment)(struct sk_buff *skb,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 123/186 gro: remove rcu_read_lock/rcu_read_unlock from gro_receive handlers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit fc1ca3348a74a1afaa7ffebc2b2f2cc149e11278 ]
All gro_receive() handlers are called from dev_gro_receive() while rcu_read_lock() has been called.
There is no point stacking more rcu_read_lock()
Stable-dep-of: 7e4196935069 ("fou: Fix null-ptr-deref in GRO.")
--- drivers/net/geneve.c | 5 +---- net/8021q/vlan_core.c | 5 +---- net/ethernet/eth.c | 5 +---- net/ipv4/af_inet.c | 12 ++++-------- net/ipv4/fou.c | 12 +++--------- net/ipv4/gre_offload.c | 9 +++------ net/ipv4/udp_offload.c | 2 -- net/ipv6/ip6_offload.c | 6 +----- net/ipv6/udp_offload.c | 2 -- 9 files changed, 14 insertions(+), 44 deletions(-)
drivers/net/geneve.c +1 -4
@@ -528,18 +528,15 @@ static struct sk_buff *geneve_gro_receive(struct sock *sk, type = gh->proto_type; -rcu_read_lock (); ptype =gro_find_receive_by_type (type);if (!ptype) - goto out_unlock; + goto out;skb_gro_pull (skb, gh_len);skb_gro_postpull_rcsum (skb, gh, gh_len); pp =call_gro_receive (ptype->callbacks.gro_receive, head, skb); flush =0 ; -out_unlock: -rcu_read_unlock (); out:skb_gro_flush_final (skb, pp, flush);
net/8021q/vlan_core.c +1 -4
@@ -482,10 +482,9 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head, type = vhdr->h_vlan_encapsulated_proto; -rcu_read_lock (); ptype =gro_find_receive_by_type (type);if (!ptype) - goto out_unlock; + goto out; flush =0 ;
@@ -504,8 +503,6 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head,skb_gro_postpull_rcsum (skb, vhdr,sizeof (*vhdr)); pp =call_gro_receive (ptype->callbacks.gro_receive, head, skb); -out_unlock: -rcu_read_unlock (); out:skb_gro_flush_final (skb, pp, flush);
net/ethernet/eth.c +1 -4
@@ -430,19 +430,16 @@ struct sk_buff *eth_gro_receive(struct list_head *head, struct sk_buff *skb) type = eh->h_proto; -rcu_read_lock (); ptype =gro_find_receive_by_type (type);if (ptype ==NULL ) { flush =1 ; - goto out_unlock; + goto out; }skb_gro_pull (skb,sizeof (*eh));skb_gro_postpull_rcsum (skb, eh,sizeof (*eh)); pp =call_gro_receive (ptype->callbacks.gro_receive, head, skb); -out_unlock: -rcu_read_unlock (); out:skb_gro_flush_final (skb, pp, flush);
net/ipv4/af_inet.c +4 -8
@@ -1471,19 +1471,18 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) proto = iph->protocol; -rcu_read_lock (); ops =rcu_dereference (inet_offloads[proto]);if (!ops || !ops->callbacks.gro_receive) - goto out_unlock; + goto out;if (*(u8 *)iph !=0x45 ) - goto out_unlock; + goto out;if (ip_is_fragment (iph)) - goto out_unlock; + goto out;if (unlikely (ip_fast_csum ((u8 *)iph,5 ))) - goto out_unlock; + goto out; id =ntohl (*(__be32 *)&iph->id); flush = (u16)((ntohl (*(__be32 *)iph) ^skb_gro_len (skb)) | (id & ~IP_DF ));
@@ -1560,9 +1559,6 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb) pp =indirect_call_gro_receive (tcp4_gro_receive, udp4_gro_receive, ops->callbacks.gro_receive, head, skb); -out_unlock: -rcu_read_unlock (); - out:skb_gro_flush_final (skb, pp, flush);
net/ipv4/fou.c +3 -9
@@ -246,17 +246,14 @@ static struct sk_buff *fou_gro_receive(struct sock *sk,/* Flag this frame as already having an outer encap header */ NAPI_GRO_CB (skb)->is_fou =1 ; -rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]);if (!ops || !ops->callbacks.gro_receive) - goto out_unlock; + goto out; pp =call_gro_receive (ops->callbacks.gro_receive, head, skb); -out_unlock: -rcu_read_unlock (); - +out:return pp; }
@@ -438,17 +435,14 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,/* Flag this frame as already having an outer encap header */ NAPI_GRO_CB (skb)->is_fou =1 ; -rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]);if (WARN_ON_ONCE (!ops || !ops->callbacks.gro_receive)) - goto out_unlock; + goto out; pp =call_gro_receive (ops->callbacks.gro_receive, head, skb); flush =0 ; -out_unlock: -rcu_read_unlock (); out:skb_gro_flush_final_remcsum (skb, pp, flush, &grc);
net/ipv4/gre_offload.c +3 -6
@@ -158,10 +158,9 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, type = greh->protocol; -rcu_read_lock (); ptype =gro_find_receive_by_type (type);if (!ptype) - goto out_unlock; + goto out; grehlen =GRE_HEADER_SECTION ;
@@ -175,13 +174,13 @@ static struct sk_buff *gre_gro_receive(struct list_head *head,if (skb_gro_header_hard (skb, hlen)) { greh =skb_gro_header_slow (skb, hlen, off);if (unlikely (!greh)) - goto out_unlock; + goto out; }/* Don't bother verifying checksum if we're going to flush anyway. */ if ((greh->flags &GRE_CSUM ) && !NAPI_GRO_CB (skb)->flush) {if (skb_gro_checksum_simple_validate (skb)) - goto out_unlock; + goto out;skb_gro_checksum_try_convert (skb,IPPROTO_GRE , null_compute_pseudo);
@@ -225,8 +224,6 @@ static struct sk_buff *gre_gro_receive(struct list_head *head, pp =call_gro_receive (ptype->callbacks.gro_receive, head, skb); flush =0 ; -out_unlock: -rcu_read_unlock (); out:skb_gro_flush_final (skb, pp, flush);
net/ipv4/udp_offload.c +0 -2
@@ -606,13 +606,11 @@ struct sk_buff *udp4_gro_receive(struct list_head *head, struct sk_buff *skb) inet_gro_compute_pseudo); skip:NAPI_GRO_CB (skb)->is_ipv6 =0 ; -rcu_read_lock ();if (static_branch_unlikely (&udp_encap_needed_key)) sk =udp4_gro_lookup_skb (skb, uh->source, uh->dest); pp =udp_gro_receive (head, skb, uh, sk); -rcu_read_unlock ();return pp; flush:
net/ipv6/ip6_offload.c +1 -5
@@ -209,7 +209,6 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, flush +=ntohs (iph->payload_len) !=skb_gro_len (skb); -rcu_read_lock (); proto = iph->nexthdr; ops =rcu_dereference (inet6_offloads[proto]);if (!ops || !ops->callbacks.gro_receive) {
@@ -222,7 +221,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, ops =rcu_dereference (inet6_offloads[proto]);if (!ops || !ops->callbacks.gro_receive) - goto out_unlock; + goto out; iph =ipv6_hdr (skb); }
@@ -280,9 +279,6 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head, pp =indirect_call_gro_receive_l4 (tcp6_gro_receive, udp6_gro_receive, ops->callbacks.gro_receive, head, skb); -out_unlock: -rcu_read_unlock (); - out:skb_gro_flush_final (skb, pp, flush);
net/ipv6/udp_offload.c +0 -2
@@ -144,13 +144,11 @@ struct sk_buff *udp6_gro_receive(struct list_head *head, struct sk_buff *skb) skip:NAPI_GRO_CB (skb)->is_ipv6 =1 ; -rcu_read_lock ();if (static_branch_unlikely (&udpv6_encap_needed_key)) sk =udp6_gro_lookup_skb (skb, uh->source, uh->dest); pp =udp_gro_receive (head, skb, uh, sk); -rcu_read_unlock ();return pp; flush:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 124/186 gro: remove rcu_read_lock/rcu_read_unlock from gro_complete handlers
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 627b94f75b82d13d1530b59155a545fd99d807db ]
All gro_complete() handlers are called from napi_gro_complete() while rcu_read_lock() has been called.
There is no point stacking more rcu_read_lock()
Stable-dep-of: 7e4196935069 ("fou: Fix null-ptr-deref in GRO.")
--- drivers/net/geneve.c | 3 --- net/8021q/vlan_core.c | 2 -- net/ethernet/eth.c | 2 -- net/ipv4/af_inet.c | 7 ++----- net/ipv4/fou.c | 13 ++++--------- net/ipv4/gre_offload.c | 3 --- net/ipv4/udp_offload.c | 2 -- net/ipv6/ip6_offload.c | 8 ++------ 8 files changed, 8 insertions(+), 32 deletions(-)
drivers/net/geneve.c +0 -3
@@ -556,13 +556,10 @@ static int geneve_gro_complete(struct sock *sk, struct sk_buff *skb, gh_len =geneve_hlen (gh); type = gh->proto_type; -rcu_read_lock (); ptype =gro_find_complete_by_type (type);if (ptype) err = ptype->callbacks.gro_complete (skb, nhoff + gh_len); -rcu_read_unlock (); -skb_set_inner_mac_header (skb, nhoff + gh_len);return err;
net/8021q/vlan_core.c +0 -2
@@ -516,12 +516,10 @@ static int vlan_gro_complete(struct sk_buff *skb, int nhoff)struct packet_offload *ptype;int err = -ENOENT ; -rcu_read_lock (); ptype =gro_find_complete_by_type (type);if (ptype) err = ptype->callbacks.gro_complete (skb, nhoff +sizeof (*vhdr)); -rcu_read_unlock ();return err; }
net/ethernet/eth.c +0 -2
@@ -457,13 +457,11 @@ int eth_gro_complete(struct sk_buff *skb, int nhoff)if (skb->encapsulation)skb_set_inner_mac_header (skb, nhoff); -rcu_read_lock (); ptype =gro_find_complete_by_type (type);if (ptype !=NULL ) err = ptype->callbacks.gro_complete (skb, nhoff +sizeof (struct ethhdr )); -rcu_read_unlock ();return err; }EXPORT_SYMBOL (eth_gro_complete);
net/ipv4/af_inet.c +2 -5
@@ -1634,10 +1634,9 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff)csum_replace2 (&iph->check, iph->tot_len, newlen); iph->tot_len = newlen; -rcu_read_lock (); ops =rcu_dereference (inet_offloads[proto]);if (WARN_ON (!ops || !ops->callbacks.gro_complete)) - goto out_unlock; + goto out;/* Only need to add sizeof(*iph) to get to the next hdr below * because any hdr with option will have been flushed in
@@ -1647,9 +1646,7 @@ int inet_gro_complete(struct sk_buff *skb, int nhoff) tcp4_gro_complete, udp4_gro_complete, skb, nhoff + sizeof(*iph)); -out_unlock: -rcu_read_unlock (); - +out:return err; }EXPORT_SYMBOL (inet_gro_complete);
net/ipv4/fou.c +4 -9
@@ -265,19 +265,16 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb,const struct net_offload *ops;int err = -ENOSYS ; -rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]);if (WARN_ON (!ops || !ops->callbacks.gro_complete)) - goto out_unlock; + goto out; err = ops->callbacks.gro_complete (skb, nhoff);skb_set_inner_mac_header (skb, nhoff); -out_unlock: -rcu_read_unlock (); - +out:return err; }
@@ -479,18 +476,16 @@ static int gue_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)return err; } -rcu_read_lock (); offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]);if (WARN_ON (!ops || !ops->callbacks.gro_complete)) - goto out_unlock; + goto out; err = ops->callbacks.gro_complete (skb, nhoff + guehlen);skb_set_inner_mac_header (skb, nhoff + guehlen); -out_unlock: -rcu_read_unlock (); +out:return err; }
net/ipv4/gre_offload.c +0 -3
@@ -248,13 +248,10 @@ static int gre_gro_complete(struct sk_buff *skb, int nhoff)if (greh->flags &GRE_CSUM ) grehlen +=GRE_HEADER_SECTION ; -rcu_read_lock (); ptype =gro_find_complete_by_type (type);if (ptype) err = ptype->callbacks.gro_complete (skb, nhoff + grehlen); -rcu_read_unlock (); -skb_set_inner_mac_header (skb, nhoff + grehlen);return err;
net/ipv4/udp_offload.c +0 -2
@@ -645,7 +645,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff, uh->len = newlen; -rcu_read_lock (); sk =INDIRECT_CALL_INET (lookup, udp6_lib_lookup_skb, udp4_lib_lookup_skb, skb, uh->source, uh->dest);if (sk &&udp_sk (sk)->gro_complete) {
@@ -661,7 +660,6 @@ int udp_gro_complete(struct sk_buff *skb, int nhoff, }else { err =udp_gro_complete_segment (skb); } -rcu_read_unlock ();if (skb->remcsum_offload)skb_shinfo (skb)->gso_type |=SKB_GSO_TUNNEL_REMCSUM ;
net/ipv6/ip6_offload.c +2 -6
@@ -328,18 +328,14 @@ INDIRECT_CALLABLE_SCOPE int ipv6_gro_complete(struct sk_buff *skb, int nhoff) iph->payload_len =htons (skb->len - nhoff -sizeof (*iph)); -rcu_read_lock (); - nhoff +=sizeof (*iph) +ipv6_exthdrs_len (iph, &ops);if (WARN_ON (!ops || !ops->callbacks.gro_complete)) - goto out_unlock; + goto out; err =INDIRECT_CALL_L4 (ops->callbacks.gro_complete, tcp6_gro_complete, udp6_gro_complete, skb, nhoff); -out_unlock: -rcu_read_unlock (); - +out:return err; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 125/186 fou: Fix null-ptr-deref in GRO.
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 7e4196935069947d8b70b09c1660b67b067e75cb ]
We observed a null-ptr-deref in fou_gro_receive() while shutting down a host. [0]
The NULL pointer is sk->sk_user_data, and the offset 8 is of protocol in struct fou.
When fou_release() is called due to netns dismantle or explicit tunnel teardown, udp_tunnel_sock_release() sets NULL to sk->sk_user_data. Then, the tunnel socket is destroyed after a single RCU grace period.
So, in-flight udp4_gro_receive() could find the socket and execute the FOU GRO handler, where sk->sk_user_data could be NULL.
Let's use rcu_dereference_sk_user_data() in fou_from_sock() and add NULL checks in FOU GRO handlers.
[0]:
BUG: kernel NULL pointer dereference, address: 0000000000000008 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 80000001032f4067 P4D 80000001032f4067 PUD 103240067 PMD 0 SMP PTI CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.216-204.855.amzn2.x86_64 #1 Hardware name: Amazon EC2 c5.large/, BIOS 1.0 10/16/2017 RIP: 0010:fou_gro_receive (net/ipv4/fou.c:233) [fou] Code: 41 5f c3 cc cc cc cc e8 e7 2e 69 f4 0f 1f 80 00 00 00 00 0f 1f 44 00 00 49 89 f8 41 54 48 89 f7 48 89 d6 49 8b 80 88 02 00 00 <0f> b6 48 08 0f b7 42 4a 66 25 fd fd 80 cc 02 66 89 42 4a 0f b6 42 RSP: 0018:ffffa330c0003d08 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffff93d9e3a6b900 RCX: 0000000000000010 RDX: ffff93d9e3a6b900 RSI: ffff93d9e3a6b900 RDI: ffff93dac2e24d08 RBP: ffff93d9e3a6b900 R08: ffff93dacbce6400 R09: 0000000000000002 R10: 0000000000000000 R11: ffffffffb5f369b0 R12: ffff93dacbce6400 R13: ffff93dac2e24d08 R14: 0000000000000000 R15: ffffffffb4edd1c0 FS: 0000000000000000(0000) GS:ffff93daee800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 0000000102140001 CR4: 00000000007706f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <IRQ> ? show_trace_log_lvl (arch/x86/kernel/dumpstack.c:259) ? __die_body.cold (arch/x86/kernel/dumpstack.c:478 arch/x86/kernel/dumpstack.c:420) ? no_context (arch/x86/mm/fault.c:752) ? exc_page_fault (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 arch/x86/mm/fault.c:1435 arch/x86/mm/fault.c:1483) ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:571) ? fou_gro_receive (net/ipv4/fou.c:233) [fou] udp_gro_receive (include/linux/netdevice.h:2552 net/ipv4/udp_offload.c:559) udp4_gro_receive (net/ipv4/udp_offload.c:604) inet_gro_receive (net/ipv4/af_inet.c:1549 (discriminator 7)) dev_gro_receive (net/core/dev.c:6035 (discriminator 4)) napi_gro_receive (net/core/dev.c:6170) ena_clean_rx_irq (drivers/amazon/net/ena/ena_netdev.c:1558) [ena] ena_io_poll (drivers/amazon/net/ena/ena_netdev.c:1742) [ena] napi_poll (net/core/dev.c:6847) net_rx_action (net/core/dev.c:6917) __do_softirq (arch/x86/include/asm/jump_label.h:25 include/linux/jump_label.h:200 include/trace/events/irq.h:142 kernel/softirq.c:299) asm_call_irq_on_stack (arch/x86/entry/entry_64.S:809) </IRQ> do_softirq_own_stack (arch/x86/include/asm/irq_stack.h:27 arch/x86/include/asm/irq_stack.h:77 arch/x86/kernel/irq_64.c:77) irq_exit_rcu (kernel/softirq.c:393 kernel/softirq.c:423 kernel/softirq.c:435) common_interrupt (arch/x86/kernel/irq.c:239) asm_common_interrupt (arch/x86/include/asm/idtentry.h:626) RIP: 0010:acpi_idle_do_entry (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 drivers/acpi/processor_idle.c:114 drivers/acpi/processor_idle.c:575) Code: 8b 15 d1 3c c4 02 ed c3 cc cc cc cc 65 48 8b 04 25 40 ef 01 00 48 8b 00 a8 08 75 eb 0f 1f 44 00 00 0f 00 2d d5 09 55 00 fb f4 <fa> c3 cc cc cc cc e9 be fc ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 RSP: 0018:ffffffffb5603e58 EFLAGS: 00000246 RAX: 0000000000004000 RBX: ffff93dac0929c00 RCX: ffff93daee833900 RDX: ffff93daee800000 RSI: ffff93daee87dc00 RDI: ffff93daee87dc64 RBP: 0000000000000001 R08: ffffffffb5e7b6c0 R09: 0000000000000044 R10: ffff93daee831b04 R11: 00000000000001cd R12: 0000000000000001 R13: ffffffffb5e7b740 R14: 0000000000000001 R15: 0000000000000000 ? sched_clock_cpu (kernel/sched/clock.c:371) acpi_idle_enter (drivers/acpi/processor_idle.c:712 (discriminator 3)) cpuidle_enter_state (drivers/cpuidle/cpuidle.c:237) cpuidle_enter (drivers/cpuidle/cpuidle.c:353) cpuidle_idle_call (kernel/sched/idle.c:158 kernel/sched/idle.c:239) do_idle (kernel/sched/idle.c:302) cpu_startup_entry (kernel/sched/idle.c:395 (discriminator 1)) start_kernel (init/main.c:1048) secondary_startup_64_no_verify (arch/x86/kernel/head_64.S:310) Modules linked in: udp_diag tcp_diag inet_diag nft_nat ipip tunnel4 dummy fou ip_tunnel nft_masq nft_chain_nat nf_nat wireguard nft_ct curve25519_x86_64 libcurve25519_generic nf_conntrack libchacha20poly1305 nf_defrag_ipv6 nf_defrag_ipv4 nft_objref chacha_x86_64 nft_counter nf_tables nfnetlink poly1305_x86_64 ip6_udp_tunnel udp_tunnel libchacha crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper mousedev psmouse button ena ptp pps_core crc32c_intel
CR2: 0000000000000008
--- net/ipv4/fou.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
net/ipv4/fou.c +24 -5
@@ -48,7 +48,7 @@ struct fou_net {static inline struct fou *fou_from_sock (struct sock *sk) { -return sk->sk_user_data; +return rcu_dereference_sk_user_data (sk); }static int fou_recv_pull (struct sk_buff *skb,struct fou *fou,size_t len)
@@ -231,9 +231,15 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, struct sk_buff *skb) {const struct net_offload __rcu **offloads; -u8 proto =fou_from_sock (sk)->protocol; +struct fou *fou =fou_from_sock (sk);const struct net_offload *ops;struct sk_buff *pp =NULL ; +u8 proto; + +if (!fou) + goto out; + + proto = fou->protocol;/* We can clear the encap_mark for FOU as we are essentially doing * one of two possible things. We are either adding an L4 tunnel
@@ -261,14 +267,24 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) {const struct net_offload __rcu **offloads; -u8 proto =fou_from_sock (sk)->protocol; +struct fou *fou =fou_from_sock (sk);const struct net_offload *ops; -int err = -ENOSYS ; +u8 proto; +int err; + +if (!fou) { + err = -ENOENT ; + goto out; + } + + proto = fou->protocol; offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]); -if (WARN_ON (!ops || !ops->callbacks.gro_complete)) +if (WARN_ON (!ops || !ops->callbacks.gro_complete)) { + err = -ENOSYS ; goto out; + } err = ops->callbacks.gro_complete (skb, nhoff);
@@ -318,6 +334,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,struct gro_remcsum grc;u8 proto; +if (!fou) + goto out; +skb_gro_remcsum_init (&grc); off =skb_gro_offset (skb);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 126/186 net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit bee2ef946d3184e99077be526567d791c473036f ]
When userspace wants to take over a fdb entry by setting it as EXTERN_LEARNED, we set both flags BR_FDB_ADDED_BY_EXT_LEARN and BR_FDB_ADDED_BY_USER in br_fdb_external_learn_add().
If the bridge updates the entry later because its port changed, we clear the BR_FDB_ADDED_BY_EXT_LEARN flag, but leave the BR_FDB_ADDED_BY_USER flag set.
If userspace then wants to take over the entry again, br_fdb_external_learn_add() sees that BR_FDB_ADDED_BY_USER and skips setting the BR_FDB_ADDED_BY_EXT_LEARN flags, thus silently ignores the update.
Fix this by always allowing to set BR_FDB_ADDED_BY_EXT_LEARN regardless if this was a user fdb entry or not.
--- net/bridge/br_fdb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/bridge/br_fdb.c +2 -4
@@ -1238,12 +1238,10 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, modified = true; } -if (test_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags)) { +if (test_and_set_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags)) {/* Refresh entry */ fdb->used = jiffies; - }else if (!test_bit (BR_FDB_ADDED_BY_USER , &fdb->flags)) { -/* Take over SW learned entry */ -set_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags); + }else { modified = true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 127/186 net: dsa: vsc73xx: fix possible subblocks range of CAPT block
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit 8e69c96df771ab469cec278edb47009351de4da6 ]
CAPT block (CPU Capture Buffer) have 7 sublocks: 0-3, 4, 6, 7. Function 'vsc73xx_is_addr_valid' allows to use only block 0 at this moment.
This patch fix it.
--- drivers/net/dsa/vitesse-vsc73xx-core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/net/dsa/vitesse-vsc73xx-core.c +8 -2
@@ -35,7 +35,7 @@#define VSC73XX_BLOCK_ANALYZER 0x2/* Only subblock 0 */ #define VSC73XX_BLOCK_MII 0x3/* Subblocks 0 and 1 */ #define VSC73XX_BLOCK_MEMINIT 0x3/* Only subblock 2 */ -#define VSC73XX_BLOCK_CAPTURE 0x4/* Only subblock 2 */ +#define VSC73XX_BLOCK_CAPTURE 0x4/* Subblocks 0-4, 6, 7 */ #define VSC73XX_BLOCK_ARBITER 0x5/* Only subblock 0 */ #define VSC73XX_BLOCK_SYSTEM 0x7/* Only subblock 0 */
@@ -371,13 +371,19 @@ int vsc73xx_is_addr_valid(u8 block, u8 subblock)break ;case VSC73XX_BLOCK_MII : -case VSC73XX_BLOCK_CAPTURE :case VSC73XX_BLOCK_ARBITER :switch (subblock) { case 0 ... 1:return 1 ; }break ; +case VSC73XX_BLOCK_CAPTURE : +switch (subblock) { + case 0 ... 4: + case 6 ... 7: +return 1 ; + } +break ; }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 128/186 ASoC: topology: Properly initialize soc_enum values
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amadeusz Sławiński <[email protected]>
[ Upstream commit 8ec2a2643544ce352f012ad3d248163199d05dfc ]
soc_tplg_denum_create_values() should properly set its values field.
--- sound/soc/soc-topology.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/soc-topology.c +2 -0
@@ -998,6 +998,8 @@ static int soc_tplg_denum_create_values(struct soc_enum *se, se->dobj.control.dvalues[i] =le32_to_cpu (ec->values[i]); } + se->items =le32_to_cpu (ec->items); + se->values = (const unsigned int *)se->dobj.control.dvalues;return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 129/186 dm init: Handle minors larger than 255
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Marzinski <[email protected]>
[ Upstream commit 140ce37fd78a629105377e17842465258a5459ef ]
dm_parse_device_entry() simply copies the minor number into dmi.dev, but the dev_t format splits the minor number between the lowest 8 bytes and highest 12 bytes. If the minor number is larger than 255, part of it will end up getting treated as the major number
Fix this by checking that the minor number is valid and then encoding it as a dev_t.
--- drivers/md/dm-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/dm-init.c +3 -1
@@ -207,8 +207,10 @@ static char __init *dm_parse_device_entry(struct dm_device *dev, char *str)strscpy (dev->dmi.uuid, field[1 ],sizeof (dev->dmi.uuid));/* minor */ if (strlen (field[2 ])) { -if (kstrtoull (field[2 ],0 , &dev->dmi.dev)) +if (kstrtoull (field[2 ],0 , &dev->dmi.dev) || + dev->dmi.dev >= (1 <<MINORBITS ))return ERR_PTR (-EINVAL ); + dev->dmi.dev =huge_encode_dev ((dev_t )dev->dmi.dev); dev->dmi.flags |=DM_PERSISTENT_DEV_FLAG ; }/* flags */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 130/186 iommu/vt-d: Handle volatile descriptor status read
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Pan <[email protected]>
[ Upstream commit b5e86a95541cea737394a1da967df4cd4d8f7182 ]
Queued invalidation wait descriptor status is volatile in that IOMMU hardware writes the data upon completion.
Use READ_ONCE() to prevent compiler optimizations which ensures memory reads every time. As a side effect, READ_ONCE() also enforces strict types and may add an extra instruction. But it should not have negative performance impact since we use cpu_relax anyway and the extra time(by adding an instruction) may allow IOMMU HW request cacheline ownership easier.
e.g. gcc 12.3
BEFORE:
81 38 ad de 00 00 cmpl $0x2,(%rax)
AFTER (with READ_ONCE())
772f: 8b 00 mov (%rax),%eax
7731: 3d ad de 00 00 cmp $0x2,%eax
//status data is 32 bit--- drivers/iommu/intel/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/dmar.c +1 -1
@@ -1333,7 +1333,7 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,*/ writel (qi->free_head << shift, iommu->reg +DMAR_IQT_REG ); -while (qi->desc_status[wait_index] !=QI_DONE ) { +while (READ_ONCE (qi->desc_status[wait_index]) !=QI_DONE ) {/* * We will leave the interrupts disabled, to prevent interrupt * context to queue another cmd while a cmd is already submitted
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 131/186 cgroup: Protect css->cgroup write under css_set_lock
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 57b56d16800e8961278ecff0dc755d46c4575092 ]
The writing of css->cgroup associated with the cgroup root in rebind_subsystems() is currently protected only by cgroup_mutex. However, the reading of css->cgroup in both proc_cpuset_show() and proc_cgroup_show() is protected just by css_set_lock. That makes the readers susceptible to racing problems like data tearing or caching. It is also a problem that can be reported by KCSAN.
This can be fixed by using READ_ONCE() and WRITE_ONCE() to access css->cgroup. Alternatively, the writing of css->cgroup can be moved under css_set_lock as well which is done by this patch.
--- kernel/cgroup/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup/cgroup.c +1 -1
@@ -1773,9 +1773,9 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)RCU_INIT_POINTER (scgrp->subsys[ssid],NULL );rcu_assign_pointer (dcgrp->subsys[ssid], css); ss->root = dst_root; - css->cgroup = dcgrp;spin_lock_irq (&css_set_lock); + css->cgroup = dcgrp;WARN_ON (!list_empty (&dcgrp->e_csets[ss->id]));list_for_each_entry_safe (cset, cset_pos, &scgrp->e_csets[ss->id], e_cset_node[ss->id]) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 132/186 um: line: always fill *error_out in setup_one_line()
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 824ac4a5edd3f7494ab1996826c4f47f8ef0f63d ]
The pointer isn't initialized by callers, but I have encountered cases where it's still printed; initialize it in all possible cases in setup_one_line().
--- arch/um/drivers/line.c | 2 ++ 1 file changed, 2 insertions(+)
arch/um/drivers/line.c +2 -0
@@ -378,6 +378,7 @@ int setup_one_line(struct line *lines, int n, char *init,parse_chan_pair (NULL , line, n, opts, error_out); err =0 ; } + *error_out ="configured as 'none'" ; }else {char *new =kstrdup (init,GFP_KERNEL );if (!new) {
@@ -401,6 +402,7 @@ int setup_one_line(struct line *lines, int n, char *init, } }if (err) { + *error_out ="failed to parse channel pair" ; line->init_str =NULL ; line->valid =0 ;kfree (new);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 133/186 devres: Initialize an uninitialized struct member
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit 56a20ad349b5c51909cf8810f7c79b288864ad33 ]
Initialize an uninitialized struct member for driver API devres_open_group().
--- drivers/base/devres.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/devres.c +1 -0
@@ -577,6 +577,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) grp->id = grp;if (id) grp->id = id; + grp->color =0 ;spin_lock_irqsave (&dev->devres_lock, flags);add_dr (dev, &grp->node[0 ]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 134/186 pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krishna Kumar <[email protected]>
[ Upstream commit 335e35b748527f0c06ded9eebb65387f60647fda ]
The hotplug driver for powerpc (pci/hotplug/pnv_php.c) causes a kernel crash when we try to hot-unplug/disable the PCIe switch/bridge from the PHB.
The crash occurs because although the MSI data structure has been released during disable/hot-unplug path and it has been assigned with NULL, still during unregistration the code was again trying to explicitly disable the MSI which causes the NULL pointer dereference and kernel crash.
The patch fixes the check during unregistration path to prevent invoking pci_disable_msi/msix() since its data structure is already freed.
--- drivers/pci/hotplug/pnv_php.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pci/hotplug/pnv_php.c +1 -2
@@ -38,7 +38,6 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, bool disable_device) {struct pci_dev *pdev = php_slot->pdev; -int irq = php_slot->irq;u16 ctrl;if (php_slot->irq >0 ) {
@@ -57,7 +56,7 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, php_slot->wq =NULL ; } -if (disable_device || irq >0 ) { +if (disable_device) {if (pdev->msix_enabled)pci_disable_msix (pdev);else if (pdev->msi_enabled)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 135/186 hwmon: (adc128d818) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 8cad724c8537fe3e0da8004646abc00290adae40 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/adc128d818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/adc128d818.c +2 -2
@@ -176,7 +176,7 @@ static ssize_t adc128_in_store(struct device *dev,mutex_lock (&data->update_lock);/* 10 mV LSB on limit registers */ - regval =clamp_val (DIV_ROUND_CLOSEST (val,10 ),0 ,255 ); + regval =DIV_ROUND_CLOSEST (clamp_val (val,0 ,2550 ),10 ); data->in[index][nr] = regval <<4 ; reg = index ==1 ?ADC128_REG_IN_MIN (nr) :ADC128_REG_IN_MAX (nr);i2c_smbus_write_byte_data (data->client, reg, regval);
@@ -214,7 +214,7 @@ static ssize_t adc128_temp_store(struct device *dev,return err;mutex_lock (&data->update_lock); - regval =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),-128 ,127 ); + regval =DIV_ROUND_CLOSEST (clamp_val (val,-128000 ,127000 ),1000 ); data->temp[index] = regval <<1 ; i2c_smbus_write_byte_data(data->client, index == 1 ? ADC128_REG_TEMP_MAX
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 136/186 hwmon: (lm95234) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit af64e3e1537896337405f880c1e9ac1f8c0c6198 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/lm95234.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/hwmon/lm95234.c +5 -4
@@ -301,7 +301,8 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr,if (ret <0 )return ret; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 , index ?255 :127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 , (index ?255 :127 ) *1000 ), +1000 );mutex_lock (&data->update_lock); data->tcrit2[index] = val;
@@ -350,7 +351,7 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr,if (ret <0 )return ret; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,255 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,255000 ),1000 );mutex_lock (&data->update_lock); data->tcrit1[index] = val;
@@ -391,7 +392,7 @@ static ssize_t tcrit1_hyst_store(struct device *dev,if (ret <0 )return ret; - val =DIV_ROUND_CLOSEST (val,1000 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-255000 ,255000 ),1000 ); val =clamp_val ((int )data->tcrit1[index] - val,0 ,31 );mutex_lock (&data->update_lock);
@@ -431,7 +432,7 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr,return ret;/* Accuracy is 1/2 degrees C */ - val =clamp_val (DIV_ROUND_CLOSEST (val,500 ),-128 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-64000 ,63500 ),500 );mutex_lock (&data->update_lock); data->toffset[index] = val;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 137/186 hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 0403e10bf0824bf0ec2bb135d4cf1c0cc3bf4bf0 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/nct6775.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/nct6775.c +1 -1
@@ -2374,7 +2374,7 @@ store_temp_offset(struct device *dev, struct device_attribute *attr,if (err <0 )return err; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),-128 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-128000 ,127000 ),1000 );mutex_lock (&data->update_lock); data->temp_offset[nr] = val;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 138/186 hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 5c1de37969b7bc0abcb20b86e91e70caebbd4f89 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/w83627ehf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/w83627ehf.c +2 -2
@@ -897,7 +897,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr,if (err <0 )return err; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,127000 ),1000 );mutex_lock (&data->update_lock); data->target_temp[nr] = val;
@@ -922,7 +922,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr,return err;/* Limit the temp to 0C - 15C */ - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,15 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,15000 ),1000 );mutex_lock (&data->update_lock); reg =w83627ehf_read_value (data,W83627EHF_REG_TOLERANCE [nr]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 139/186 libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
In reply to Greg Kroah-Hartman5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Ziegler <[email protected]>
[ Upstream commit cedc12c5b57f7efa6dbebfb2b140e8675f5a2616 ]
In the current state, an erroneous call to bpf_object__find_map_by_name(NULL, ...) leads to a segmentation fault through the following call chain:
bpf_object__find_map_by_name(obj = NULL, ...)
-> bpf_object__for_each_map(pos, obj = NULL)
-> bpf_object__next_map((obj = NULL), NULL)
-> return (obj = NULL)->maps
While calling bpf_object__find_map_by_name with obj = NULL is obviously incorrect, this should not lead to a segmentation fault but rather be handled gracefully.
As __bpf_map__iter already handles this situation correctly, we can delegate the check for the regular case there and only add a check in case the prev or next parameter is NULL.
--- tools/lib/bpf/libbpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/lib/bpf/libbpf.c +2 -2
@@ -9005,7 +9005,7 @@ __bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i)struct bpf_map *bpf_map__next (const struct bpf_map *prev,const struct bpf_object *obj) { -if (prev ==NULL ) +if (prev ==NULL && obj !=NULL )return obj->maps;return __bpf_map__iter (prev, obj,1 );
@@ -9014,7 +9014,7 @@ bpf_map__next(const struct bpf_map *prev, const struct bpf_object *obj)struct bpf_map *bpf_map__prev (const struct bpf_map *next,const struct bpf_object *obj) { -if (next ==NULL ) { +if (next ==NULL && obj !=NULL ) {if (!obj->nr_maps)return NULL ;return obj->maps + obj->nr_maps -1 ;
Signature · 1 line
2.43.0