This is the start of the stable review cycle for the 5.10.205 release. There are 62 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Dec 2023 13:50:31 +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.205-rc... 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 gregkh@linuxfoundation.org Linux 5.10.205-rc1
Naveen N Rao naveen@kernel.org powerpc/ftrace: Fix stack teardown in ftrace_no_trace
Naveen N Rao naveen@kernel.org powerpc/ftrace: Create a dummy stackframe to fix stack unwind
Mazin Al Haddad mazinalhaddad05@gmail.com tty: n_gsm: add sanity check for gsm->receive in gsm_receive_buf()
Jiri Slaby jirislaby@kernel.org tty: n_gsm, remove duplicates of parameters
Daniel Starke daniel.starke@siemens.com tty: n_gsm: fix tty registration before control channel open
Roy Luo royluo@google.com USB: gadget: core: adjust uevent timing on gadget unbind
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Fix a race in rb_time_cmpxchg() for 32 bit archs
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Fix writing to the buffer with max_data_size
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Have saved event hold the entire event
Steven Rostedt (Google) rostedt@goodmis.org tracing: Update snapshot buffer on resize if it is allocated
Steven Rostedt (Google) rostedt@goodmis.org ring-buffer: Fix memory leak of free page
Florent Revest revest@chromium.org team: Fix use-after-free when an option instance allocation fails
James Houghton jthoughton@google.com arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify
Baokun Li libaokun1@huawei.com ext4: prevent the normalized size from exceeding EXT_MAX_BLOCKS
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org soundwire: stream: fix NULL pointer dereference for multi_link
Mark Rutland mark.rutland@arm.com perf: Fix perf_event_validate_size() lockdep splat
Denis Benato benato.denis96@gmail.com HID: hid-asus: add const to read-only outgoing usb buffer
Lech Perczak lech.perczak@gmail.com net: usb: qmi_wwan: claim interface 4 for ZTE MF290
Linus Torvalds torvalds@linux-foundation.org asm-generic: qspinlock: fix queued_spin_value_unlocked() implementation
Aoba K nexp_0x17@outlook.com HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad
Denis Benato benato.denis96@gmail.com HID: hid-asus: reset the backlight brightness level on resume
Oliver Neukum oneukum@suse.com HID: add ALWAYS_POLL quirk for Apple kb
Brett Raye braye@fastmail.com HID: glorious: fix Glorious Model I HID report
Andy Shevchenko andriy.shevchenko@linux.intel.com platform/x86: intel_telemetry: Fix kernel doc descriptions
Coly Li colyli@suse.de bcache: avoid NULL checking to c->root in run_cache_set()
Coly Li colyli@suse.de bcache: add code comments for bch_btree_node_get() and __bch_btree_node_alloc()
Colin Ian King colin.i.king@gmail.com bcache: remove redundant assignment to variable cur_idx
Coly Li colyli@suse.de bcache: avoid oversize memory allocation by small stripe_size
Ming Lei ming.lei@redhat.com blk-throttle: fix lockdep warning of "cgroup_mutex or RCU read lock required!"
Oliver Neukum oneukum@suse.com usb: aqc111: check packet for fixup for true limit
Jason-JH.Lin jason-jh.lin@mediatek.com drm/mediatek: Add spinlock for setting vblank event in atomic_begin
Maxime Ripard maxime@cerno.tech drm: Use state helper instead of CRTC state pointer
Maxime Ripard maxime@cerno.tech drm/atomic: Pass the full state to CRTC atomic begin and flush
Jiaxun Yang jiaxun.yang@flygoat.com PCI: loongson: Limit MRRS to 256
Bjorn Helgaas bhelgaas@google.com Revert "PCI: acpiphp: Reassign resources on bridge if necessary"
Hartmut Knaack knaack.h@gmx.de ALSA: hda/realtek: Apply mute LED quirk for HP15-db
Kai Vehmanen kai.vehmanen@linux.intel.com ALSA: hda/hdmi: add force-connect quirks for ASUSTeK Z170 variants
Hangyu Hua hbh25y@gmail.com fuse: dax: set fc->dax to NULL in fuse_dax_conn_free()
Jens Axboe axboe@kernel.dk cred: switch to using atomic_long_t
Igor Russkikh irusskikh@marvell.com net: atlantic: fix double free in ring reinit logic
Hyunwoo Kim v4bel@theori.io appletalk: Fix Use-After-Free in atalk_ioctl
Andrew Halaney ahalaney@redhat.com net: stmmac: Handle disabled MDIO busses from devicetree
Rasmus Villemoes linux@rasmusvillemoes.dk net: stmmac: use dev_err_probe() for reporting mdio bus registration failure
Nikolay Kuratov kniv@yandex-team.ru vsock/virtio: Fix unsigned integer wrap around in virtio_transport_has_space()
Yusong Gao a869920004@gmail.com sign-file: Fix incorrect return values check
David Arinzon darinzon@amazon.com net: ena: Fix XDP redirection error
David Arinzon darinzon@amazon.com net: ena: Destroy correct number of xdp queues upon failure
Dong Chenchen dongchenchen2@huawei.com net: Remove acked SYN flag from packet in the transmit queue correctly
Dinghao Liu dinghao.liu@zju.edu.cn qed: Fix a potential use-after-free in qed_cxt_tables_alloc
Hyunwoo Kim v4bel@theori.io net/rose: Fix Use-After-Free in rose_ioctl
Hyunwoo Kim v4bel@theori.io atm: Fix Use-After-Free in do_vcc_ioctl
Radu Bulie radu-andrei.bulie@nxp.com net: fec: correct queue selection
Vladimir Oltean vladimir.oltean@nxp.com net: vlan: introduce skb_vlan_eth_hdr()
Chengfeng Ye dg573847474@gmail.com atm: solos-pci: Fix potential deadlock on &tx_queue_lock
Chengfeng Ye dg573847474@gmail.com atm: solos-pci: Fix potential deadlock on &cli_queue_lock
Stefan Wahren wahrenst@gmx.net qca_spi: Fix reset behavior
Stefan Wahren wahrenst@gmx.net qca_debug: Fix ethtool -G iface tx behavior
Stefan Wahren wahrenst@gmx.net qca_debug: Prevent crash on TX ring changes
Maciej Żenczykowski maze@google.com net: ipv6: support reporting otherwise unknown prefix flags in RTM_NEWPREFIX
Mikhail Khvainitski me@khvoinitsky.org HID: lenovo: Restrict detection of patched firmware only to USB cptkbd
David Howells dhowells@redhat.com afs: Fix refcount underflow from error handling race
Florian Westphal fw@strlen.de netfilter: nf_tables: fix 'exist' matching on bigendian arches
-------------
Diffstat:
Makefile | 4 +- arch/arm64/include/asm/pgtable.h | 6 + arch/powerpc/kernel/trace/ftrace_64_mprofile.S | 17 ++- block/blk-throttle.c | 2 + drivers/atm/solos-pci.c | 8 +- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 8 +- drivers/gpu/drm/arm/hdlcd_crtc.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c | 12 +- drivers/gpu/drm/ast/ast_mode.c | 9 +- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 4 +- drivers/gpu/drm/drm_atomic_helper.c | 8 +- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 +- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 4 +- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 4 +- drivers/gpu/drm/imx/dcss/dcss-crtc.c | 4 +- drivers/gpu/drm/imx/ipuv3-crtc.c | 4 +- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 22 ++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 24 ++-- drivers/gpu/drm/meson/meson_crtc.c | 4 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 +- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 4 +- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 +- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 14 ++- drivers/gpu/drm/sti/sti_crtc.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_crtc.c | 6 +- drivers/gpu/drm/tegra/dc.c | 12 +- drivers/gpu/drm/tidss/tidss_crtc.c | 4 +- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 +- drivers/gpu/drm/vc4/vc4_hvs.c | 4 +- drivers/gpu/drm/virtio/virtgpu_display.c | 6 +- drivers/gpu/drm/vkms/vkms_crtc.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 4 +- drivers/gpu/drm/xlnx/zynqmp_disp.c | 4 +- drivers/gpu/drm/zte/zx_vou.c | 2 +- drivers/hid/hid-asus.c | 25 +++- drivers/hid/hid-glorious.c | 16 ++- drivers/hid/hid-ids.h | 11 +- drivers/hid/hid-lenovo.c | 3 +- drivers/hid/hid-multitouch.c | 5 + drivers/hid/hid-quirks.c | 1 + drivers/md/bcache/bcache.h | 1 + drivers/md/bcache/btree.c | 7 ++ drivers/md/bcache/super.c | 4 +- drivers/md/bcache/writeback.c | 2 +- drivers/net/ethernet/amazon/ena/ena_eth_com.c | 3 - drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 +- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 +- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- drivers/net/ethernet/freescale/fec_main.c | 27 ++--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 +- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 1 + drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 4 +- drivers/net/ethernet/qualcomm/qca_debug.c | 17 +-- drivers/net/ethernet/qualcomm/qca_spi.c | 20 +++- drivers/net/ethernet/sfc/tx_tso.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 8 +- drivers/net/team/team.c | 4 +- drivers/net/usb/aqc111.c | 8 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/pci/controller/pci-loongson.c | 46 +++++++- drivers/pci/hotplug/acpiphp_glue.c | 9 +- drivers/platform/x86/intel_telemetry_core.c | 4 +- drivers/soundwire/stream.c | 7 +- drivers/staging/gdm724x/gdm_lte.c | 4 +- drivers/tty/n_gsm.c | 131 +++++++++++++-------- drivers/usb/gadget/udc/core.c | 4 +- fs/afs/rxrpc.c | 2 +- fs/ext4/mballoc.c | 4 + fs/fuse/dax.c | 1 + include/asm-generic/qspinlock.h | 2 +- include/drm/drm_modeset_helper_vtables.h | 4 +- include/linux/cred.h | 8 +- include/linux/if_vlan.h | 12 +- include/net/addrconf.h | 12 +- include/net/if_inet6.h | 4 - kernel/cred.c | 64 +++++----- kernel/events/core.c | 10 ++ kernel/trace/ring_buffer.c | 18 ++- kernel/trace/trace.c | 4 +- net/appletalk/ddp.c | 9 +- net/atm/ioctl.c | 7 +- net/batman-adv/soft-interface.c | 2 +- net/ipv4/tcp_output.c | 6 + net/ipv6/addrconf.c | 6 +- net/netfilter/nft_exthdr.c | 2 +- net/netfilter/nft_fib.c | 8 +- net/rose/af_rose.c | 4 +- net/vmw_vsock/virtio_transport_common.c | 2 +- scripts/sign-file.c | 12 +- sound/pci/hda/patch_hdmi.c | 2 + sound/pci/hda/patch_realtek.c | 1 + 105 files changed, 564 insertions(+), 312 deletions(-)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal fw@strlen.de
[ Upstream commit 63331e37fb227e796894b31d713697612c8dee7f ]
Maze reports "tcp option fastopen exists" fails to match on OpenWrt 22.03.5, r20134-5f15225c1e (5.10.176) router.
"tcp option fastopen exists" translates to: inet [ exthdr load tcpopt 1b @ 34 + 0 present => reg 1 ] [ cmp eq reg 1 0x00000001 ]
.. but existing nft userspace generates a 1-byte compare.
On LSB (x86), "*reg32 = 1" is identical to nft_reg_store8(reg32, 1), but not on MSB, which will place the 1 last. IOW, on bigendian aches the cmp8 is awalys false.
Make sure we store this in a consistent fashion, so existing userspace will also work on MSB (bigendian).
Regardless of this patch we can also change nft userspace to generate 'reg32 == 0' and 'reg32 != 0' instead of u8 == 0 // u8 == 1 when adding 'option x missing/exists' expressions as well.
Fixes: 3c1fece8819e ("netfilter: nft_exthdr: Allow checking TCP option presence, too") Fixes: b9f9a485fb0e ("netfilter: nft_exthdr: add boolean DCCP option matching") Fixes: 055c4b34b94f ("netfilter: nft_fib: Support existence check") Reported-by: Maciej Żenczykowski zenczykowski@gmail.com Closes: https://lore.kernel.org/netfilter-devel/CAHo-OozyEqHUjL2-ntATzeZOiuftLWZ_HU6... Signed-off-by: Florian Westphal fw@strlen.de Acked-by: Phil Sutter phil@nwl.cc Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nft_exthdr.c | 2 +- net/netfilter/nft_fib.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index cb69a299f10c5..c9f89f035ccff 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c @@ -214,7 +214,7 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,
offset = i + priv->offset; if (priv->flags & NFT_EXTHDR_F_PRESENT) { - *dest = 1; + nft_reg_store8(dest, 1); } else { if (priv->len % NFT_REG32_SIZE) dest[priv->len / NFT_REG32_SIZE] = 0; diff --git a/net/netfilter/nft_fib.c b/net/netfilter/nft_fib.c index b10ce732b337c..1fd4b2054e8f7 100644 --- a/net/netfilter/nft_fib.c +++ b/net/netfilter/nft_fib.c @@ -140,11 +140,15 @@ void nft_fib_store_result(void *reg, const struct nft_fib *priv, switch (priv->result) { case NFT_FIB_RESULT_OIF: index = dev ? dev->ifindex : 0; - *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index; + if (priv->flags & NFTA_FIB_F_PRESENT) + nft_reg_store8(dreg, !!index); + else + *dreg = index; + break; case NFT_FIB_RESULT_OIFNAME: if (priv->flags & NFTA_FIB_F_PRESENT) - *dreg = !!dev; + nft_reg_store8(dreg, !!dev); else strncpy(reg, dev ? dev->name : "", IFNAMSIZ); break;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells dhowells@redhat.com
[ Upstream commit 52bf9f6c09fca8c74388cd41cc24e5d1bff812a9 ]
If an AFS cell that has an unreachable (eg. ENETUNREACH) server listed (VL server or fileserver), an asynchronous probe to one of its addresses may fail immediately because sendmsg() returns an error. When this happens, a refcount underflow can happen if certain events hit a very small window.
The way this occurs is:
(1) There are two levels of "call" object, the afs_call and the rxrpc_call. Each of them can be transitioned to a "completed" state in the event of success or failure.
(2) Asynchronous afs_calls are self-referential whilst they are active to prevent them from evaporating when they're not being processed. This reference is disposed of when the afs_call is completed.
Note that an afs_call may only be completed once; once completed completing it again will do nothing.
(3) When a call transmission is made, the app-side rxrpc code queues a Tx buffer for the rxrpc I/O thread to transmit. The I/O thread invokes sendmsg() to transmit it - and in the case of failure, it transitions the rxrpc_call to the completed state.
(4) When an rxrpc_call is completed, the app layer is notified. In this case, the app is kafs and it schedules a work item to process events pertaining to an afs_call.
(5) When the afs_call event processor is run, it goes down through the RPC-specific handler to afs_extract_data() to retrieve data from rxrpc - and, in this case, it picks up the error from the rxrpc_call and returns it.
The error is then propagated to the afs_call and that is completed too. At this point the self-reference is released.
(6) If the rxrpc I/O thread manages to complete the rxrpc_call within the window between rxrpc_send_data() queuing the request packet and checking for call completion on the way out, then rxrpc_kernel_send_data() will return the error from sendmsg() to the app.
(7) Then afs_make_call() will see an error and will jump to the error handling path which will attempt to clean up the afs_call.
(8) The problem comes when the error handling path in afs_make_call() tries to unconditionally drop an async afs_call's self-reference. This self-reference, however, may already have been dropped by afs_extract_data() completing the afs_call
(9) The refcount underflows when we return to afs_do_probe_vlserver() and that tries to drop its reference on the afs_call.
Fix this by making afs_make_call() attempt to complete the afs_call rather than unconditionally putting it. That way, if afs_extract_data() manages to complete the call first, afs_make_call() won't do anything.
The bug can be forced by making do_udp_sendmsg() return -ENETUNREACH and sticking an msleep() in rxrpc_send_data() after the 'success:' label to widen the race window.
The error message looks something like:
refcount_t: underflow; use-after-free. WARNING: CPU: 3 PID: 720 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110 ... RIP: 0010:refcount_warn_saturate+0xba/0x110 ... afs_put_call+0x1dc/0x1f0 [kafs] afs_fs_get_capabilities+0x8b/0xe0 [kafs] afs_fs_probe_fileserver+0x188/0x1e0 [kafs] afs_lookup_server+0x3bf/0x3f0 [kafs] afs_alloc_server_list+0x130/0x2e0 [kafs] afs_create_volume+0x162/0x400 [kafs] afs_get_tree+0x266/0x410 [kafs] vfs_get_tree+0x25/0xc0 fc_mount+0xe/0x40 afs_d_automount+0x1b3/0x390 [kafs] __traverse_mounts+0x8f/0x210 step_into+0x340/0x760 path_openat+0x13a/0x1260 do_filp_open+0xaf/0x160 do_sys_openat2+0xaf/0x170
or something like:
refcount_t: underflow; use-after-free. ... RIP: 0010:refcount_warn_saturate+0x99/0xda ... afs_put_call+0x4a/0x175 afs_send_vl_probes+0x108/0x172 afs_select_vlserver+0xd6/0x311 afs_do_cell_detect_alias+0x5e/0x1e9 afs_cell_detect_alias+0x44/0x92 afs_validate_fc+0x9d/0x134 afs_get_tree+0x20/0x2e6 vfs_get_tree+0x1d/0xc9 fc_mount+0xe/0x33 afs_d_automount+0x48/0x9d __traverse_mounts+0xe0/0x166 step_into+0x140/0x274 open_last_lookups+0x1c1/0x1df path_openat+0x138/0x1c3 do_filp_open+0x55/0xb4 do_sys_openat2+0x6c/0xb6
Fixes: 34fa47612bfe ("afs: Fix race in async call refcounting") Reported-by: Bill MacAllister bill@ca-zephyr.org Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1052304 Suggested-by: Jeffrey E Altman jaltman@auristor.com Signed-off-by: David Howells dhowells@redhat.com Reviewed-by: Jeffrey Altman jaltman@auristor.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Link: https://lore.kernel.org/r/2633992.1702073229@warthog.procyon.org.uk/ # v1 Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/afs/rxrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 535d28b44bca3..1820b53657a6c 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -491,7 +491,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp) if (call->async) { if (cancel_work_sync(&call->async_work)) afs_put_call(call); - afs_put_call(call); + afs_set_call_complete(call, ret, 0); }
ac->error = ret;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Khvainitski me@khvoinitsky.org
[ Upstream commit 43527a0094c10dfbf0d5a2e7979395a38de3ff65 ]
Commit 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround") introduced a regression for ThinkPad TrackPoint Keyboard II which has similar quirks to cptkbd (so it uses the same workarounds) but slightly different so that there are false-positives during detecting well-behaving firmware. This commit restricts detecting well-behaving firmware to the only model which known to have one and have stable enough quirks to not cause false-positives.
Fixes: 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround") Link: https://lore.kernel.org/linux-input/ZXRiiPsBKNasioqH@jekhomev/ Link: https://bbs.archlinux.org/viewtopic.php?pid=2135468#p2135468 Signed-off-by: Mikhail Khvainitski me@khvoinitsky.org Tested-by: Yauhen Kharuzhy jekhor@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-lenovo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 71f7b0d539df5..249af8d26fe78 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -489,7 +489,8 @@ static int lenovo_event_cptkbd(struct hid_device *hdev, * so set middlebutton_state to 3 * to never apply workaround anymore */ - if (cptkbd_data->middlebutton_state == 1 && + if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && + cptkbd_data->middlebutton_state == 1 && usage->type == EV_REL && (usage->code == REL_X || usage->code == REL_Y)) { cptkbd_data->middlebutton_state = 3;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej Żenczykowski maze@google.com
[ Upstream commit bd4a816752bab609dd6d65ae021387beb9e2ddbd ]
Lorenzo points out that we effectively clear all unknown flags from PIO when copying them to userspace in the netlink RTM_NEWPREFIX notification.
We could fix this one at a time as new flags are defined, or in one fell swoop - I choose the latter.
We could either define 6 new reserved flags (reserved1..6) and handle them individually (and rename them as new flags are defined), or we could simply copy the entire unmodified byte over - I choose the latter.
This unfortunately requires some anonymous union/struct magic, so we add a static assert on the struct size for a little extra safety.
Cc: David Ahern dsahern@kernel.org Cc: Lorenzo Colitti lorenzo@google.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Maciej Żenczykowski maze@google.com Reviewed-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/addrconf.h | 12 ++++++++++-- include/net/if_inet6.h | 4 ---- net/ipv6/addrconf.c | 6 +----- 3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index edba74a536839..4d0c4cf1d4c88 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -31,17 +31,22 @@ struct prefix_info { __u8 length; __u8 prefix_len;
+ union __packed { + __u8 flags; + struct __packed { #if defined(__BIG_ENDIAN_BITFIELD) - __u8 onlink : 1, + __u8 onlink : 1, autoconf : 1, reserved : 6; #elif defined(__LITTLE_ENDIAN_BITFIELD) - __u8 reserved : 6, + __u8 reserved : 6, autoconf : 1, onlink : 1; #else #error "Please fix <asm/byteorder.h>" #endif + }; + }; __be32 valid; __be32 prefered; __be32 reserved2; @@ -49,6 +54,9 @@ struct prefix_info { struct in6_addr prefix; };
+/* rfc4861 4.6.2: IPv6 PIO is 32 bytes in size */ +static_assert(sizeof(struct prefix_info) == 32); + #include <linux/ipv6.h> #include <linux/netdevice.h> #include <net/if_inet6.h> diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index e03ba8e80781a..d4d7f4d52b152 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -22,10 +22,6 @@ #define IF_RS_SENT 0x10 #define IF_READY 0x80000000
-/* prefix flags */ -#define IF_PREFIX_ONLINK 0x01 -#define IF_PREFIX_AUTOCONF 0x02 - enum { INET6_IFADDR_STATE_PREDAD, INET6_IFADDR_STATE_DAD, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 193e5f2757330..79787a1f5ab34 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -6034,11 +6034,7 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, pmsg->prefix_len = pinfo->prefix_len; pmsg->prefix_type = pinfo->type; pmsg->prefix_pad3 = 0; - pmsg->prefix_flags = 0; - if (pinfo->onlink) - pmsg->prefix_flags |= IF_PREFIX_ONLINK; - if (pinfo->autoconf) - pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; + pmsg->prefix_flags = pinfo->flags;
if (nla_put(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix)) goto nla_put_failure;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren wahrenst@gmx.net
[ Upstream commit f4e6064c97c050bd9904925ff7d53d0c9954fc7b ]
The qca_spi driver stop and restart the SPI kernel thread (via ndo_stop & ndo_open) in case of TX ring changes. This is a big issue because it allows userspace to prevent restart of the SPI kernel thread (via signals). A subsequent change of TX ring wrongly assume a valid spi_thread pointer which result in a crash.
So prevent this by stopping the network traffic handling and temporary park the SPI thread.
Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Signed-off-by: Stefan Wahren wahrenst@gmx.net Link: https://lore.kernel.org/r/20231206141222.52029-2-wahrenst@gmx.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qualcomm/qca_debug.c | 9 ++++----- drivers/net/ethernet/qualcomm/qca_spi.c | 12 ++++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c index 702aa217a27ad..4c6c1792fdc77 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.c +++ b/drivers/net/ethernet/qualcomm/qca_debug.c @@ -258,7 +258,6 @@ qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) static int qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { - const struct net_device_ops *ops = dev->netdev_ops; struct qcaspi *qca = netdev_priv(dev);
if ((ring->rx_pending) || @@ -266,14 +265,14 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) (ring->rx_jumbo_pending)) return -EINVAL;
- if (netif_running(dev)) - ops->ndo_stop(dev); + if (qca->spi_thread) + kthread_park(qca->spi_thread);
qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN); qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN);
- if (netif_running(dev)) - ops->ndo_open(dev); + if (qca->spi_thread) + kthread_unpark(qca->spi_thread);
return 0; } diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index 44fa959ebcaa5..b08a4b2a6a996 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -573,6 +573,18 @@ qcaspi_spi_thread(void *data) netdev_info(qca->net_dev, "SPI thread created\n"); while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_park()) { + netif_tx_disable(qca->net_dev); + netif_carrier_off(qca->net_dev); + qcaspi_flush_tx_ring(qca); + kthread_parkme(); + if (qca->sync == QCASPI_SYNC_READY) { + netif_carrier_on(qca->net_dev); + netif_wake_queue(qca->net_dev); + } + continue; + } + if ((qca->intr_req == qca->intr_svc) && !qca->txr.skb[qca->txr.head]) schedule();
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren wahrenst@gmx.net
[ Upstream commit 96a7e861d9e04d07febd3011c30cd84cd141d81f ]
After calling ethtool -g it was not possible to adjust the TX ring size again:
# ethtool -g eth1 Ring parameters for eth1: Pre-set maximums: RX: 4 RX Mini: n/a RX Jumbo: n/a TX: 10 Current hardware settings: RX: 4 RX Mini: n/a RX Jumbo: n/a TX: 10 # ethtool -G eth1 tx 8 netlink error: Invalid argument
The reason for this is that the readonly setting rx_pending get initialized and after that the range check in qcaspi_set_ringparam() fails regardless of the provided parameter. So fix this by accepting the exposed RX defaults. Instead of adding another magic number better use a new define here.
Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Suggested-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Stefan Wahren wahrenst@gmx.net Link: https://lore.kernel.org/r/20231206141222.52029-3-wahrenst@gmx.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qualcomm/qca_debug.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qualcomm/qca_debug.c b/drivers/net/ethernet/qualcomm/qca_debug.c index 4c6c1792fdc77..66229b300c5a4 100644 --- a/drivers/net/ethernet/qualcomm/qca_debug.c +++ b/drivers/net/ethernet/qualcomm/qca_debug.c @@ -30,6 +30,8 @@
#define QCASPI_MAX_REGS 0x20
+#define QCASPI_RX_MAX_FRAMES 4 + static const u16 qcaspi_spi_regs[] = { SPI_REG_BFR_SIZE, SPI_REG_WRBUF_SPC_AVA, @@ -249,9 +251,9 @@ qcaspi_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { struct qcaspi *qca = netdev_priv(dev);
- ring->rx_max_pending = 4; + ring->rx_max_pending = QCASPI_RX_MAX_FRAMES; ring->tx_max_pending = TX_RING_MAX_LEN; - ring->rx_pending = 4; + ring->rx_pending = QCASPI_RX_MAX_FRAMES; ring->tx_pending = qca->txr.count; }
@@ -260,7 +262,7 @@ qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { struct qcaspi *qca = netdev_priv(dev);
- if ((ring->rx_pending) || + if (ring->rx_pending != QCASPI_RX_MAX_FRAMES || (ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren wahrenst@gmx.net
[ Upstream commit 1057812d146dd658c9a9a96d869c2551150207b5 ]
In case of a reset triggered by the QCA7000 itself, the behavior of the qca_spi driver was not quite correct: - in case of a pending RX frame decoding the drop counter must be incremented and decoding state machine reseted - also the reset counter must always be incremented regardless of sync state
Fixes: 291ab06ecf67 ("net: qualcomm: new Ethernet over SPI driver for QCA7000") Signed-off-by: Stefan Wahren wahrenst@gmx.net Link: https://lore.kernel.org/r/20231206141222.52029-4-wahrenst@gmx.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qualcomm/qca_spi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c index b08a4b2a6a996..ffa1846f5b4c4 100644 --- a/drivers/net/ethernet/qualcomm/qca_spi.c +++ b/drivers/net/ethernet/qualcomm/qca_spi.c @@ -613,11 +613,17 @@ qcaspi_spi_thread(void *data) if (intr_cause & SPI_INT_CPU_ON) { qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON);
+ /* Frame decoding in progress */ + if (qca->frm_handle.state != qca->frm_handle.init) + qca->net_dev->stats.rx_dropped++; + + qcafrm_fsm_init_spi(&qca->frm_handle); + qca->stats.device_reset++; + /* not synced. */ if (qca->sync != QCASPI_SYNC_READY) continue;
- qca->stats.device_reset++; netif_wake_queue(qca->net_dev); netif_carrier_on(qca->net_dev); }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye dg573847474@gmail.com
[ Upstream commit d5dba32b8f6cb39be708b726044ba30dbc088b30 ]
As &card->cli_queue_lock is acquired under softirq context along the following call chain from solos_bh(), other acquisition of the same lock inside process context should disable at least bh to avoid double lock.
<deadlock #1> console_show() --> spin_lock(&card->cli_queue_lock) <interrupt> --> solos_bh() --> spin_lock(&card->cli_queue_lock)
This flaw was found by an experimental static analysis tool I am developing for irq-related deadlock.
To prevent the potential deadlock, the patch uses spin_lock_bh() on the card->cli_queue_lock under process context code consistently to prevent the possible deadlock scenario.
Fixes: 9c54004ea717 ("atm: Driver for Solos PCI ADSL2+ card.") Signed-off-by: Chengfeng Ye dg573847474@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/atm/solos-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 94fbc3abe60e6..95f768b28a5e6 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -449,9 +449,9 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, struct sk_buff *skb; unsigned int len;
- spin_lock(&card->cli_queue_lock); + spin_lock_bh(&card->cli_queue_lock); skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); - spin_unlock(&card->cli_queue_lock); + spin_unlock_bh(&card->cli_queue_lock); if(skb == NULL) return sprintf(buf, "No data.\n");
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye dg573847474@gmail.com
[ Upstream commit 15319a4e8ee4b098118591c6ccbd17237f841613 ]
As &card->tx_queue_lock is acquired under softirq context along the following call chain from solos_bh(), other acquisition of the same lock inside process context should disable at least bh to avoid double lock.
<deadlock #2> pclose() --> spin_lock(&card->tx_queue_lock) <interrupt> --> solos_bh() --> fpga_tx() --> spin_lock(&card->tx_queue_lock)
This flaw was found by an experimental static analysis tool I am developing for irq-related deadlock.
To prevent the potential deadlock, the patch uses spin_lock_bh() on &card->tx_queue_lock under process context code consistently to prevent the possible deadlock scenario.
Fixes: 213e85d38912 ("solos-pci: clean up pclose() function") Signed-off-by: Chengfeng Ye dg573847474@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/atm/solos-pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 95f768b28a5e6..d3c30a28c410e 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -956,14 +956,14 @@ static void pclose(struct atm_vcc *vcc) struct pkt_hdr *header;
/* Remove any yet-to-be-transmitted packets from the pending queue */ - spin_lock(&card->tx_queue_lock); + spin_lock_bh(&card->tx_queue_lock); skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) { if (SKB_CB(skb)->vcc == vcc) { skb_unlink(skb, &card->tx_queue[port]); solos_pop(vcc, skb); } } - spin_unlock(&card->tx_queue_lock); + spin_unlock_bh(&card->tx_queue_lock);
skb = alloc_skb(sizeof(*header), GFP_KERNEL); if (!skb) {
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 1f5020acb33f926030f62563c86dffca35c7b701 ]
Similar to skb_eth_hdr() introduced in commit 96cc4b69581d ("macvlan: do not assume mac_header is set in macvlan_broadcast()"), let's introduce a skb_vlan_eth_hdr() helper which can be used in TX-only code paths to get to the VLAN header based on skb->data rather than based on the skb_mac_header(skb).
We also consolidate the drivers that dereference skb->data to go through this helper.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Eric Dumazet edumazet@google.com Reviewed-by: Simon Horman simon.horman@corigine.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Stable-dep-of: 9fc95fe95c3e ("net: fec: correct queue selection") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 +-- drivers/net/ethernet/emulex/benet/be_main.c | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 2 +- drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 4 ++-- drivers/net/ethernet/sfc/tx_tso.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 ++----- drivers/staging/gdm724x/gdm_lte.c | 4 ++-- include/linux/if_vlan.h | 12 ++++++++++-- net/batman-adv/soft-interface.c | 2 +- 12 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4f669e7c75587..4509a29ff73f9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1924,8 +1924,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
/* Skip VLAN tag if present */ if (ether_type == ETH_P_8021Q) { - struct vlan_ethhdr *vhdr = - (struct vlan_ethhdr *)skb->data; + struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb);
ether_type = ntohs(vhdr->h_vlan_encapsulated_proto); } diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 52b399aa3213d..edd4dd73b3e32 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1125,7 +1125,7 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, struct be_wrb_params *wrb_params) { - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; + struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb); unsigned int eth_hdr_len; struct iphdr *ip;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 4df5e91e86ce7..a4ab3e7efa5e4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -1002,7 +1002,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring, if (unlikely(rc < 0)) return rc;
- vhdr = (struct vlan_ethhdr *)skb->data; + vhdr = skb_vlan_eth_hdr(skb); vhdr->h_vlan_TCI |= cpu_to_be16((skb->priority << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 88d8f17cefd8e..57667ccc28f54 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2879,7 +2879,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, rc = skb_cow_head(skb, 0); if (rc < 0) return rc; - vhdr = (struct vlan_ethhdr *)skb->data; + vhdr = skb_vlan_eth_hdr(skb); vhdr->h_vlan_TCI = htons(tx_flags >> I40E_TX_FLAGS_VLAN_SHIFT); } else { diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 2b100b7b325a5..5829d81f2cb11 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -8707,7 +8707,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
if (skb_cow_head(skb, 0)) goto out_drop; - vhdr = (struct vlan_ethhdr *)skb->data; + vhdr = skb_vlan_eth_hdr(skb); vhdr->h_vlan_TCI = htons(tx_flags >> IXGBE_TX_FLAGS_VLAN_SHIFT); } else { diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index e2046b6d65a30..2c54600835643 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1861,7 +1861,7 @@ netxen_tso_check(struct net_device *netdev,
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
- vh = (struct vlan_ethhdr *)skb->data; + vh = skb_vlan_eth_hdr(skb); protocol = vh->h_vlan_encapsulated_proto; flags = FLAGS_VLAN_TAGGED;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index bdf15d2a64313..7260e57d79f2e 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -317,7 +317,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
if (adapter->flags & QLCNIC_VLAN_FILTERING) { if (protocol == ETH_P_8021Q) { - vh = (struct vlan_ethhdr *)skb->data; + vh = skb_vlan_eth_hdr(skb); vlan_id = ntohs(vh->h_vlan_TCI); } else if (skb_vlan_tag_present(skb)) { vlan_id = skb_vlan_tag_get(skb); @@ -467,7 +467,7 @@ static int qlcnic_tx_pkt(struct qlcnic_adapter *adapter, u32 producer = tx_ring->producer;
if (protocol == ETH_P_8021Q) { - vh = (struct vlan_ethhdr *)skb->data; + vh = skb_vlan_eth_hdr(skb); flags = QLCNIC_FLAGS_VLAN_TAGGED; vlan_tci = ntohs(vh->h_vlan_TCI); protocol = ntohs(vh->h_vlan_encapsulated_proto); diff --git a/drivers/net/ethernet/sfc/tx_tso.c b/drivers/net/ethernet/sfc/tx_tso.c index 898e5c61d9086..d381d8164f07c 100644 --- a/drivers/net/ethernet/sfc/tx_tso.c +++ b/drivers/net/ethernet/sfc/tx_tso.c @@ -147,7 +147,7 @@ static __be16 efx_tso_check_protocol(struct sk_buff *skb) EFX_WARN_ON_ONCE_PARANOID(((struct ethhdr *)skb->data)->h_proto != protocol); if (protocol == htons(ETH_P_8021Q)) { - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; + struct vlan_ethhdr *veh = skb_vlan_eth_hdr(skb);
protocol = veh->h_vlan_encapsulated_proto; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 59a07a01e80ca..709bd81fde2a8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3660,13 +3660,10 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb) { - struct vlan_ethhdr *veth; - __be16 vlan_proto; + struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb); + __be16 vlan_proto = veth->h_vlan_proto; u16 vlanid;
- veth = (struct vlan_ethhdr *)skb->data; - vlan_proto = veth->h_vlan_proto; - if ((vlan_proto == htons(ETH_P_8021Q) && dev->features & NETIF_F_HW_VLAN_CTAG_RX) || (vlan_proto == htons(ETH_P_8021AD) && diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index de30262c3fae0..e0787647093d1 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -350,7 +350,7 @@ static s32 gdm_lte_tx_nic_type(struct net_device *dev, struct sk_buff *skb) /* Get ethernet protocol */ eth = (struct ethhdr *)skb->data; if (ntohs(eth->h_proto) == ETH_P_8021Q) { - vlan_eth = (struct vlan_ethhdr *)skb->data; + vlan_eth = skb_vlan_eth_hdr(skb); mac_proto = ntohs(vlan_eth->h_vlan_encapsulated_proto); network_data = skb->data + VLAN_ETH_HLEN; nic_type |= NIC_TYPE_F_VLAN; @@ -436,7 +436,7 @@ static netdev_tx_t gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) * driver based on the NIC mac */ if (nic_type & NIC_TYPE_F_VLAN) { - struct vlan_ethhdr *vlan_eth = (struct vlan_ethhdr *)skb->data; + struct vlan_ethhdr *vlan_eth = skb_vlan_eth_hdr(skb);
nic->vlan_id = ntohs(vlan_eth->h_vlan_TCI) & VLAN_VID_MASK; data_buf = skb->data + (VLAN_ETH_HLEN - ETH_HLEN); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 4e7e72f3da5bd..ce6714bec65fd 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -60,6 +60,14 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) return (struct vlan_ethhdr *)skb_mac_header(skb); }
+/* Prefer this version in TX path, instead of + * skb_reset_mac_header() + vlan_eth_hdr() + */ +static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb) +{ + return (struct vlan_ethhdr *)skb->data; +} + #define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ #define VLAN_PRIO_SHIFT 13 #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */ @@ -526,7 +534,7 @@ static inline void __vlan_hwaccel_put_tag(struct sk_buff *skb, */ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci) { - struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data; + struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
if (!eth_type_vlan(veth->h_vlan_proto)) return -EINVAL; @@ -727,7 +735,7 @@ static inline bool skb_vlan_tagged_multi(struct sk_buff *skb) if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) return false;
- veh = (struct vlan_ethhdr *)skb->data; + veh = skb_vlan_eth_hdr(skb); protocol = veh->h_vlan_encapsulated_proto; }
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 7ac16d7b94a2f..0e6d0a5e68413 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -454,7 +454,7 @@ void batadv_interface_rx(struct net_device *soft_iface, if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) goto dropped;
- vhdr = (struct vlan_ethhdr *)skb->data; + vhdr = skb_vlan_eth_hdr(skb);
/* drop batman-in-batman packets to prevent loops */ if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN))
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radu Bulie radu-andrei.bulie@nxp.com
[ Upstream commit 9fc95fe95c3e2a63ced8eeca4b256518ab204b63 ]
The old implementation extracted VLAN TCI info from the payload before the VLAN tag has been pushed in the payload.
Another problem was that the VLAN TCI was extracted even if the packet did not have VLAN protocol header.
This resulted in invalid VLAN TCI and as a consequence a random queue was computed.
This patch fixes the above issues and use the VLAN TCI from the skb if it is present or VLAN TCI from payload if present. If no VLAN header is present queue 0 is selected.
Fixes: 52c4a1a85f4b ("net: fec: add ndo_select_queue to fix TX bandwidth fluctuations") Signed-off-by: Radu Bulie radu-andrei.bulie@nxp.com Signed-off-by: Wei Fang wei.fang@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/fec_main.c | 27 +++++++++-------------- 1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index e18b3b72fc0df..4ce913559c91d 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3266,31 +3266,26 @@ static int fec_set_features(struct net_device *netdev, return 0; }
-static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) -{ - struct vlan_ethhdr *vhdr; - unsigned short vlan_TCI = 0; - - if (skb->protocol == htons(ETH_P_ALL)) { - vhdr = (struct vlan_ethhdr *)(skb->data); - vlan_TCI = ntohs(vhdr->h_vlan_TCI); - } - - return vlan_TCI; -} - static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, struct net_device *sb_dev) { struct fec_enet_private *fep = netdev_priv(ndev); - u16 vlan_tag; + u16 vlan_tag = 0;
if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) return netdev_pick_tx(ndev, skb, NULL);
- vlan_tag = fec_enet_get_raw_vlan_tci(skb); - if (!vlan_tag) + /* VLAN is present in the payload.*/ + if (eth_type_vlan(skb->protocol)) { + struct vlan_ethhdr *vhdr = skb_vlan_eth_hdr(skb); + + vlan_tag = ntohs(vhdr->h_vlan_TCI); + /* VLAN is present in the skb but not yet pushed in the payload.*/ + } else if (skb_vlan_tag_present(skb)) { + vlan_tag = skb->vlan_tci; + } else { return vlan_tag; + }
return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim v4bel@theori.io
[ Upstream commit 24e90b9e34f9e039f56b5f25f6e6eb92cdd8f4b3 ]
Because do_vcc_ioctl() accesses sk->sk_receive_queue without holding a sk->sk_receive_queue.lock, it can cause a race with vcc_recvmsg(). A use-after-free for skb occurs with the following flow. ``` do_vcc_ioctl() -> skb_peek() vcc_recvmsg() -> skb_recv_datagram() -> skb_free_datagram() ``` Add sk->sk_receive_queue.lock to do_vcc_ioctl() to fix this issue.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Hyunwoo Kim v4bel@theori.io Link: https://lore.kernel.org/r/20231209094210.GA403126@v4bel-B760M-AORUS-ELITE-AX Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/atm/ioctl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 838ebf0cabbfb..f81f8d56f5c0c 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c @@ -73,14 +73,17 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, case SIOCINQ: { struct sk_buff *skb; + int amount;
if (sock->state != SS_CONNECTED) { error = -EINVAL; goto done; } + spin_lock_irq(&sk->sk_receive_queue.lock); skb = skb_peek(&sk->sk_receive_queue); - error = put_user(skb ? skb->len : 0, - (int __user *)argp) ? -EFAULT : 0; + amount = skb ? skb->len : 0; + spin_unlock_irq(&sk->sk_receive_queue.lock); + error = put_user(amount, (int __user *)argp) ? -EFAULT : 0; goto done; } case ATM_SETSC:
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim v4bel@theori.io
[ Upstream commit 810c38a369a0a0ce625b5c12169abce1dd9ccd53 ]
Because rose_ioctl() accesses sk->sk_receive_queue without holding a sk->sk_receive_queue.lock, it can cause a race with rose_accept(). A use-after-free for skb occurs with the following flow. ``` rose_ioctl() -> skb_peek() rose_accept() -> skb_dequeue() -> kfree_skb() ``` Add sk->sk_receive_queue.lock to rose_ioctl() to fix this issue.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Hyunwoo Kim v4bel@theori.io Link: https://lore.kernel.org/r/20231209100538.GA407321@v4bel-B760M-AORUS-ELITE-AX Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/rose/af_rose.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 86c93cf1744b0..b3e7a92f1ec19 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1307,9 +1307,11 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case TIOCINQ: { struct sk_buff *skb; long amount = 0L; - /* These two are safe on a single CPU system as only user tasks fiddle here */ + + spin_lock_irq(&sk->sk_receive_queue.lock); if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) amount = skb->len; + spin_unlock_irq(&sk->sk_receive_queue.lock); return put_user(amount, (unsigned int __user *) argp); }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit b65d52ac9c085c0c52dee012a210d4e2f352611b ]
qed_ilt_shadow_alloc() will call qed_ilt_shadow_free() to free p_hwfn->p_cxt_mngr->ilt_shadow on error. However, qed_cxt_tables_alloc() accesses the freed pointer on failure of qed_ilt_shadow_alloc() through calling qed_cxt_mngr_free(), which may lead to use-after-free. Fix this issue by setting p_mngr->ilt_shadow to NULL in qed_ilt_shadow_free().
Fixes: fe56b9e6a8d9 ("qed: Add module with basic common support") Reviewed-by: Przemek Kitszel przemyslaw.kitszel@intel.com Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Link: https://lore.kernel.org/r/20231210045255.21383-1-dinghao.liu@zju.edu.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qed/qed_cxt.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index 0a22f8ce9a2c3..1c3737921b6cf 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c @@ -933,6 +933,7 @@ static void qed_ilt_shadow_free(struct qed_hwfn *p_hwfn) p_dma->virt_addr = NULL; } kfree(p_mngr->ilt_shadow); + p_mngr->ilt_shadow = NULL; }
static int qed_ilt_blk_alloc(struct qed_hwfn *p_hwfn,
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Chenchen dongchenchen2@huawei.com
[ Upstream commit f99cd56230f56c8b6b33713c5be4da5d6766be1f ]
syzkaller report:
kernel BUG at net/core/skbuff.c:3452! invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.7.0-rc4-00009-gbee0e7762ad2-dirty #135 RIP: 0010:skb_copy_and_csum_bits (net/core/skbuff.c:3452) Call Trace: icmp_glue_bits (net/ipv4/icmp.c:357) __ip_append_data.isra.0 (net/ipv4/ip_output.c:1165) ip_append_data (net/ipv4/ip_output.c:1362 net/ipv4/ip_output.c:1341) icmp_push_reply (net/ipv4/icmp.c:370) __icmp_send (./include/net/route.h:252 net/ipv4/icmp.c:772) ip_fragment.constprop.0 (./include/linux/skbuff.h:1234 net/ipv4/ip_output.c:592 net/ipv4/ip_output.c:577) __ip_finish_output (net/ipv4/ip_output.c:311 net/ipv4/ip_output.c:295) ip_output (net/ipv4/ip_output.c:427) __ip_queue_xmit (net/ipv4/ip_output.c:535) __tcp_transmit_skb (net/ipv4/tcp_output.c:1462) __tcp_retransmit_skb (net/ipv4/tcp_output.c:3387) tcp_retransmit_skb (net/ipv4/tcp_output.c:3404) tcp_retransmit_timer (net/ipv4/tcp_timer.c:604) tcp_write_timer (./include/linux/spinlock.h:391 net/ipv4/tcp_timer.c:716)
The panic issue was trigered by tcp simultaneous initiation. The initiation process is as follows:
TCP A TCP B
1. CLOSED CLOSED
2. SYN-SENT --> <SEQ=100><CTL=SYN> ...
3. SYN-RECEIVED <-- <SEQ=300><CTL=SYN> <-- SYN-SENT
4. ... <SEQ=100><CTL=SYN> --> SYN-RECEIVED
5. SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...
// TCP B: not send challenge ack for ack limit or packet loss // TCP A: close tcp_close tcp_send_fin if (!tskb && tcp_under_memory_pressure(sk)) tskb = skb_rb_last(&sk->tcp_rtx_queue); //pick SYN_ACK packet TCP_SKB_CB(tskb)->tcp_flags |= TCPHDR_FIN; // set FIN flag
6. FIN_WAIT_1 --> <SEQ=100><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ...
// TCP B: send challenge ack to SYN_FIN_ACK
7. ... <SEQ=301><ACK=101><CTL=ACK> <-- SYN-RECEIVED //challenge ack
// TCP A: <SND.UNA=101>
8. FIN_WAIT_1 --> <SEQ=101><ACK=301><END_SEQ=102><CTL=SYN,FIN,ACK> ... // retransmit panic
__tcp_retransmit_skb //skb->len=0 tcp_trim_head len = tp->snd_una - TCP_SKB_CB(skb)->seq // len=101-100 __pskb_trim_head skb->data_len -= len // skb->len=-1, wrap around ... ... ip_fragment icmp_glue_bits //BUG_ON
If we use tcp_trim_head() to remove acked SYN from packet that contains data or other flags, skb->len will be incorrectly decremented. We can remove SYN flag that has been acked from rtx_queue earlier than tcp_trim_head(), which can fix the problem mentioned above.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Co-developed-by: Eric Dumazet edumazet@google.com Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: Dong Chenchen dongchenchen2@huawei.com Link: https://lore.kernel.org/r/20231210020200.1539875-1-dongchenchen2@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_output.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f8ad8465f76cb..f0df14782ee01 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3171,7 +3171,13 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) if (skb_still_in_host_queue(sk, skb)) return -EBUSY;
+start: if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) { + if (unlikely(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN)) { + TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_SYN; + TCP_SKB_CB(skb)->seq++; + goto start; + } if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) { WARN_ON_ONCE(1); return -EINVAL;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Arinzon darinzon@amazon.com
[ Upstream commit 41db6f99b5489a0d2ef26afe816ef0c6118d1d47 ]
The ena_setup_and_create_all_xdp_queues() function freed all the resources upon failure, after creating only xdp_num_queues queues, instead of freeing just the created ones.
In this patch, the only resources that are freed, are the ones allocated right before the failure occurs.
Fixes: 548c4940b9f1 ("net: ena: Implement XDP_TX action") Signed-off-by: Shahar Itzko itzko@amazon.com Signed-off-by: David Arinzon darinzon@amazon.com Link: https://lore.kernel.org/r/20231211062801.27891-2-darinzon@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c index 1722d4091ea3f..e13ae04d2f0fd 100644 --- a/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -77,6 +77,8 @@ static void ena_unmap_tx_buff(struct ena_ring *tx_ring, struct ena_tx_buffer *tx_info); static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter, int first_index, int count); +static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter, + int first_index, int count);
static void ena_tx_timeout(struct net_device *dev, unsigned int txqueue) { @@ -388,23 +390,22 @@ static void ena_init_all_xdp_queues(struct ena_adapter *adapter)
static int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter) { + u32 xdp_first_ring = adapter->xdp_first_ring; + u32 xdp_num_queues = adapter->xdp_num_queues; int rc = 0;
- rc = ena_setup_tx_resources_in_range(adapter, adapter->xdp_first_ring, - adapter->xdp_num_queues); + rc = ena_setup_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); if (rc) goto setup_err;
- rc = ena_create_io_tx_queues_in_range(adapter, - adapter->xdp_first_ring, - adapter->xdp_num_queues); + rc = ena_create_io_tx_queues_in_range(adapter, xdp_first_ring, xdp_num_queues); if (rc) goto create_err;
return 0;
create_err: - ena_free_all_io_tx_resources(adapter); + ena_free_all_io_tx_resources_in_range(adapter, xdp_first_ring, xdp_num_queues); setup_err: return rc; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Arinzon darinzon@amazon.com
[ Upstream commit 4ab138ca0a340e6d6e7a6a9bd5004bd8f83127ca ]
When sending TX packets, the meta descriptor can be all zeroes as no meta information is required (as in XDP).
This patch removes the validity check, as when `disable_meta_caching` is enabled, such TX packets will be dropped otherwise.
Fixes: 0e3a3f6dacf0 ("net: ena: support new LLQ acceleration mode") Signed-off-by: Shay Agroskin shayagr@amazon.com Signed-off-by: David Arinzon darinzon@amazon.com Link: https://lore.kernel.org/r/20231211062801.27891-5-darinzon@amazon.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amazon/ena/ena_eth_com.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.c b/drivers/net/ethernet/amazon/ena/ena_eth_com.c index 032ab9f204388..3af9dbf245f2a 100644 --- a/drivers/net/ethernet/amazon/ena/ena_eth_com.c +++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.c @@ -316,9 +316,6 @@ static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, * compare it to the stored version, just create the meta */ if (io_sq->disable_meta_caching) { - if (unlikely(!ena_tx_ctx->meta_valid)) - return -EINVAL; - *have_meta = true; return ena_com_create_meta(io_sq, ena_meta); }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yusong Gao a869920004@gmail.com
[ Upstream commit 829649443e78d85db0cff0c37cadb28fbb1a5f6f ]
There are some wrong return values check in sign-file when call OpenSSL API. The ERR() check cond is wrong because of the program only check the return value is < 0 which ignored the return val is 0. For example: 1. CMS_final() return 1 for success or 0 for failure. 2. i2d_CMS_bio_stream() returns 1 for success or 0 for failure. 3. i2d_TYPEbio() return 1 for success and 0 for failure. 4. BIO_free() return 1 for success and 0 for failure.
Link: https://www.openssl.org/docs/manmaster/man3/ Fixes: e5a2e3c84782 ("scripts/sign-file.c: Add support for signing with a raw signature") Signed-off-by: Yusong Gao a869920004@gmail.com Reviewed-by: Juerg Haefliger juerg.haefliger@canonical.com Signed-off-by: David Howells dhowells@redhat.com Link: https://lore.kernel.org/r/20231213024405.624692-1-a869920004@gmail.com/ # v5 Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/sign-file.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/scripts/sign-file.c b/scripts/sign-file.c index 7434e9ea926e2..12acc70e5a7a5 100644 --- a/scripts/sign-file.c +++ b/scripts/sign-file.c @@ -322,7 +322,7 @@ int main(int argc, char **argv) CMS_NOSMIMECAP | use_keyid | use_signed_attrs), "CMS_add1_signer"); - ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) < 0, + ERR(CMS_final(cms, bm, NULL, CMS_NOCERTS | CMS_BINARY) != 1, "CMS_final");
#else @@ -341,10 +341,10 @@ int main(int argc, char **argv) b = BIO_new_file(sig_file_name, "wb"); ERR(!b, "%s", sig_file_name); #ifndef USE_PKCS7 - ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) < 0, + ERR(i2d_CMS_bio_stream(b, cms, NULL, 0) != 1, "%s", sig_file_name); #else - ERR(i2d_PKCS7_bio(b, pkcs7) < 0, + ERR(i2d_PKCS7_bio(b, pkcs7) != 1, "%s", sig_file_name); #endif BIO_free(b); @@ -374,9 +374,9 @@ int main(int argc, char **argv)
if (!raw_sig) { #ifndef USE_PKCS7 - ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) < 0, "%s", dest_name); + ERR(i2d_CMS_bio_stream(bd, cms, NULL, 0) != 1, "%s", dest_name); #else - ERR(i2d_PKCS7_bio(bd, pkcs7) < 0, "%s", dest_name); + ERR(i2d_PKCS7_bio(bd, pkcs7) != 1, "%s", dest_name); #endif } else { BIO *b; @@ -396,7 +396,7 @@ int main(int argc, char **argv) ERR(BIO_write(bd, &sig_info, sizeof(sig_info)) < 0, "%s", dest_name); ERR(BIO_write(bd, magic_number, sizeof(magic_number) - 1) < 0, "%s", dest_name);
- ERR(BIO_free(bd) < 0, "%s", dest_name); + ERR(BIO_free(bd) != 1, "%s", dest_name);
/* Finally, if we're signing in place, replace the original. */ if (replace_orig)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Kuratov kniv@yandex-team.ru
[ Upstream commit 60316d7f10b17a7ebb1ead0642fee8710e1560e0 ]
We need to do signed arithmetic if we expect condition `if (bytes < 0)` to be possible
Found by Linux Verification Center (linuxtesting.org) with SVACE
Fixes: 06a8fc78367d ("VSOCK: Introduce virtio_vsock_common.ko") Signed-off-by: Nikolay Kuratov kniv@yandex-team.ru Reviewed-by: Stefano Garzarella sgarzare@redhat.com Link: https://lore.kernel.org/r/20231211162317.4116625-1-kniv@yandex-team.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/vmw_vsock/virtio_transport_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index c9ee9259af48a..080e8f2bf9855 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -436,7 +436,7 @@ static s64 virtio_transport_has_space(struct vsock_sock *vsk) struct virtio_vsock_sock *vvs = vsk->trans; s64 bytes;
- bytes = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); + bytes = (s64)vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); if (bytes < 0) bytes = 0;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rasmus Villemoes linux@rasmusvillemoes.dk
[ Upstream commit 839612d23ffd933174db911ce56dc3f3ca883ec5 ]
I have a board where these two lines are always printed during boot:
imx-dwmac 30bf0000.ethernet: Cannot register the MDIO bus imx-dwmac 30bf0000.ethernet: stmmac_dvr_probe: MDIO bus (id: 1) registration failed
It's perfectly fine, and the device is successfully (and silently, as far as the console goes) probed later.
Use dev_err_probe() instead, which will demote these messages to debug level (thus removing the alarming messages from the console) when the error is -EPROBE_DEFER, and also has the advantage of including the error code if/when it happens to be something other than -EPROBE_DEFER.
While here, add the missing \n to one of the format strings.
Signed-off-by: Rasmus Villemoes linux@rasmusvillemoes.dk Link: https://lore.kernel.org/r/20220602074840.1143360-1-linux@rasmusvillemoes.dk Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: e23c0d21ce92 ("net: stmmac: Handle disabled MDIO busses from devicetree") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 709bd81fde2a8..8416a186cd7f3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5187,9 +5187,9 @@ int stmmac_dvr_probe(struct device *device, /* MDIO bus Registration */ ret = stmmac_mdio_register(ndev); if (ret < 0) { - dev_err(priv->device, - "%s: MDIO bus (id: %d) registration failed", - __func__, priv->plat->bus_id); + dev_err_probe(priv->device, ret, + "%s: MDIO bus (id: %d) registration failed\n", + __func__, priv->plat->bus_id); goto error_mdio_register; } } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 7c1a14b256da3..ecc7f4842f849 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -460,7 +460,7 @@ int stmmac_mdio_register(struct net_device *ndev)
err = of_mdiobus_register(new_bus, mdio_node); if (err != 0) { - dev_err(dev, "Cannot register the MDIO bus\n"); + dev_err_probe(dev, err, "Cannot register the MDIO bus\n"); goto bus_register_fail; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Halaney ahalaney@redhat.com
[ Upstream commit e23c0d21ce9234fbc31ece35663ababbb83f9347 ]
Many hardware configurations have the MDIO bus disabled, and are instead using some other MDIO bus to talk to the MAC's phy.
of_mdiobus_register() returns -ENODEV in this case. Let's handle it gracefully instead of failing to probe the MAC.
Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet controllers.") Signed-off-by: Andrew Halaney ahalaney@redhat.com Reviewed-by: Serge Semin fancer.lancer@gmail.com Link: https://lore.kernel.org/r/20231212-b4-stmmac-handle-mdio-enodev-v2-1-600171a... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index ecc7f4842f849..d9b76e1e09493 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -459,7 +459,11 @@ int stmmac_mdio_register(struct net_device *ndev) new_bus->parent = priv->device;
err = of_mdiobus_register(new_bus, mdio_node); - if (err != 0) { + if (err == -ENODEV) { + err = 0; + dev_info(dev, "MDIO bus is disabled\n"); + goto bus_register_fail; + } else if (err) { dev_err_probe(dev, err, "Cannot register the MDIO bus\n"); goto bus_register_fail; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim v4bel@theori.io
[ Upstream commit 189ff16722ee36ced4d2a2469d4ab65a8fee4198 ]
Because atalk_ioctl() accesses sk->sk_receive_queue without holding a sk->sk_receive_queue.lock, it can cause a race with atalk_recvmsg(). A use-after-free for skb occurs with the following flow. ``` atalk_ioctl() -> skb_peek() atalk_recvmsg() -> skb_recv_datagram() -> skb_free_datagram() ``` Add sk->sk_receive_queue.lock to atalk_ioctl() to fix this issue.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Hyunwoo Kim v4bel@theori.io Link: https://lore.kernel.org/r/20231213041056.GA519680@v4bel-B760M-AORUS-ELITE-AX Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/appletalk/ddp.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index c94b212d8e7ca..46adb8cefccf2 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1811,15 +1811,14 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; } case TIOCINQ: { - /* - * These two are safe on a single CPU system as only - * user tasks fiddle here - */ - struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + struct sk_buff *skb; long amount = 0;
+ spin_lock_irq(&sk->sk_receive_queue.lock); + skb = skb_peek(&sk->sk_receive_queue); if (skb) amount = skb->len - sizeof(struct ddpehdr); + spin_unlock_irq(&sk->sk_receive_queue.lock); rc = put_user(amount, (int __user *)argp); break; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Russkikh irusskikh@marvell.com
[ Upstream commit 7bb26ea74aa86fdf894b7dbd8c5712c5b4187da7 ]
Driver has a logic leak in ring data allocation/free, where double free may happen in aq_ring_free if system is under stress and driver init/deinit is happening.
The probability is higher to get this during suspend/resume cycle.
Verification was done simulating same conditions with
stress -m 2000 --vm-bytes 20M --vm-hang 10 --backoff 1000 while true; do sudo ifconfig enp1s0 down; sudo ifconfig enp1s0 up; done
Fixed by explicitly clearing pointers to NULL on deallocation
Fixes: 018423e90bee ("net: ethernet: aquantia: Add ring support code") Reported-by: Linus Torvalds torvalds@linux-foundation.org Closes: https://lore.kernel.org/netdev/CAHk-=wiZZi7FcvqVSUirHBjx0bBUZ4dFrMDVLc3+3HCr... Signed-off-by: Igor Russkikh irusskikh@marvell.com Link: https://lore.kernel.org/r/20231213094044.22988-1-irusskikh@marvell.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index e9c6f1fa0b1a7..98e8997f80366 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -577,11 +577,14 @@ void aq_ring_free(struct aq_ring_s *self) return;
kfree(self->buff_ring); + self->buff_ring = NULL;
- if (self->dx_ring) + if (self->dx_ring) { dma_free_coherent(aq_nic_get_dev(self->aq_nic), self->size * self->dx_size, self->dx_ring, self->dx_ring_pa); + self->dx_ring = NULL; + } }
unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
commit f8fa5d76925991976b3e7076f9d1052515ec1fca upstream.
There are multiple ways to grab references to credentials, and the only protection we have against overflowing it is the memory required to do so.
With memory sizes only moving in one direction, let's bump the reference count to 64-bit and move it outside the realm of feasibly overflowing.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/cred.h | 8 +++--- kernel/cred.c | 64 +++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 36 deletions(-)
--- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -109,7 +109,7 @@ static inline int groups_search(const st * same context as task->real_cred. */ struct cred { - atomic_t usage; + atomic_long_t usage; #ifdef CONFIG_DEBUG_CREDENTIALS atomic_t subscribers; /* number of processes subscribed */ void *put_addr; @@ -227,7 +227,7 @@ static inline bool cap_ambient_invariant */ static inline struct cred *get_new_cred(struct cred *cred) { - atomic_inc(&cred->usage); + atomic_long_inc(&cred->usage); return cred; }
@@ -259,7 +259,7 @@ static inline const struct cred *get_cre struct cred *nonconst_cred = (struct cred *) cred; if (!cred) return NULL; - if (!atomic_inc_not_zero(&nonconst_cred->usage)) + if (!atomic_long_inc_not_zero(&nonconst_cred->usage)) return NULL; validate_creds(cred); nonconst_cred->non_rcu = 0; @@ -283,7 +283,7 @@ static inline void put_cred(const struct
if (cred) { validate_creds(cred); - if (atomic_dec_and_test(&(cred)->usage)) + if (atomic_long_dec_and_test(&(cred)->usage)) __put_cred(cred); } } --- a/kernel/cred.c +++ b/kernel/cred.c @@ -98,17 +98,17 @@ static void put_cred_rcu(struct rcu_head
#ifdef CONFIG_DEBUG_CREDENTIALS if (cred->magic != CRED_MAGIC_DEAD || - atomic_read(&cred->usage) != 0 || + atomic_long_read(&cred->usage) != 0 || read_cred_subscribers(cred) != 0) panic("CRED: put_cred_rcu() sees %p with" - " mag %x, put %p, usage %d, subscr %d\n", + " mag %x, put %p, usage %ld, subscr %d\n", cred, cred->magic, cred->put_addr, - atomic_read(&cred->usage), + atomic_long_read(&cred->usage), read_cred_subscribers(cred)); #else - if (atomic_read(&cred->usage) != 0) - panic("CRED: put_cred_rcu() sees %p with usage %d\n", - cred, atomic_read(&cred->usage)); + if (atomic_long_read(&cred->usage) != 0) + panic("CRED: put_cred_rcu() sees %p with usage %ld\n", + cred, atomic_long_read(&cred->usage)); #endif
security_cred_free(cred); @@ -131,11 +131,11 @@ static void put_cred_rcu(struct rcu_head */ void __put_cred(struct cred *cred) { - kdebug("__put_cred(%p{%d,%d})", cred, - atomic_read(&cred->usage), + kdebug("__put_cred(%p{%ld,%d})", cred, + atomic_long_read(&cred->usage), read_cred_subscribers(cred));
- BUG_ON(atomic_read(&cred->usage) != 0); + BUG_ON(atomic_long_read(&cred->usage) != 0); #ifdef CONFIG_DEBUG_CREDENTIALS BUG_ON(read_cred_subscribers(cred) != 0); cred->magic = CRED_MAGIC_DEAD; @@ -158,8 +158,8 @@ void exit_creds(struct task_struct *tsk) { struct cred *cred;
- kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, - atomic_read(&tsk->cred->usage), + kdebug("exit_creds(%u,%p,%p,{%ld,%d})", tsk->pid, tsk->real_cred, tsk->cred, + atomic_long_read(&tsk->cred->usage), read_cred_subscribers(tsk->cred));
cred = (struct cred *) tsk->real_cred; @@ -218,7 +218,7 @@ struct cred *cred_alloc_blank(void) if (!new) return NULL;
- atomic_set(&new->usage, 1); + atomic_long_set(&new->usage, 1); #ifdef CONFIG_DEBUG_CREDENTIALS new->magic = CRED_MAGIC; #endif @@ -265,7 +265,7 @@ struct cred *prepare_creds(void) memcpy(new, old, sizeof(struct cred));
new->non_rcu = 0; - atomic_set(&new->usage, 1); + atomic_long_set(&new->usage, 1); set_cred_subscribers(new, 0); get_group_info(new->group_info); get_uid(new->user); @@ -348,8 +348,8 @@ int copy_creds(struct task_struct *p, un p->real_cred = get_cred(p->cred); get_cred(p->cred); alter_cred_subscribers(p->cred, 2); - kdebug("share_creds(%p{%d,%d})", - p->cred, atomic_read(&p->cred->usage), + kdebug("share_creds(%p{%ld,%d})", + p->cred, atomic_long_read(&p->cred->usage), read_cred_subscribers(p->cred)); atomic_inc(&p->cred->user->processes); return 0; @@ -439,8 +439,8 @@ int commit_creds(struct cred *new) struct task_struct *task = current; const struct cred *old = task->real_cred;
- kdebug("commit_creds(%p{%d,%d})", new, - atomic_read(&new->usage), + kdebug("commit_creds(%p{%ld,%d})", new, + atomic_long_read(&new->usage), read_cred_subscribers(new));
BUG_ON(task->cred != old); @@ -449,7 +449,7 @@ int commit_creds(struct cred *new) validate_creds(old); validate_creds(new); #endif - BUG_ON(atomic_read(&new->usage) < 1); + BUG_ON(atomic_long_read(&new->usage) < 1);
get_cred(new); /* we will require a ref for the subj creds too */
@@ -522,14 +522,14 @@ EXPORT_SYMBOL(commit_creds); */ void abort_creds(struct cred *new) { - kdebug("abort_creds(%p{%d,%d})", new, - atomic_read(&new->usage), + kdebug("abort_creds(%p{%ld,%d})", new, + atomic_long_read(&new->usage), read_cred_subscribers(new));
#ifdef CONFIG_DEBUG_CREDENTIALS BUG_ON(read_cred_subscribers(new) != 0); #endif - BUG_ON(atomic_read(&new->usage) < 1); + BUG_ON(atomic_long_read(&new->usage) < 1); put_cred(new); } EXPORT_SYMBOL(abort_creds); @@ -545,8 +545,8 @@ const struct cred *override_creds(const { const struct cred *old = current->cred;
- kdebug("override_creds(%p{%d,%d})", new, - atomic_read(&new->usage), + kdebug("override_creds(%p{%ld,%d})", new, + atomic_long_read(&new->usage), read_cred_subscribers(new));
validate_creds(old); @@ -568,8 +568,8 @@ const struct cred *override_creds(const rcu_assign_pointer(current->cred, new); alter_cred_subscribers(old, -1);
- kdebug("override_creds() = %p{%d,%d}", old, - atomic_read(&old->usage), + kdebug("override_creds() = %p{%ld,%d}", old, + atomic_long_read(&old->usage), read_cred_subscribers(old)); return old; } @@ -586,8 +586,8 @@ void revert_creds(const struct cred *old { const struct cred *override = current->cred;
- kdebug("revert_creds(%p{%d,%d})", old, - atomic_read(&old->usage), + kdebug("revert_creds(%p{%ld,%d})", old, + atomic_long_read(&old->usage), read_cred_subscribers(old));
validate_creds(old); @@ -699,7 +699,7 @@ struct cred *prepare_kernel_cred(struct
*new = *old; new->non_rcu = 0; - atomic_set(&new->usage, 1); + atomic_long_set(&new->usage, 1); set_cred_subscribers(new, 0); get_uid(new->user); get_user_ns(new->user_ns); @@ -809,8 +809,8 @@ static void dump_invalid_creds(const str cred == tsk->cred ? "[eff]" : ""); printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n", cred->magic, cred->put_addr); - printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n", - atomic_read(&cred->usage), + printk(KERN_ERR "CRED: ->usage=%ld, subscr=%d\n", + atomic_long_read(&cred->usage), read_cred_subscribers(cred)); printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", from_kuid_munged(&init_user_ns, cred->uid), @@ -882,9 +882,9 @@ EXPORT_SYMBOL(__validate_process_creds); */ void validate_creds_for_do_exit(struct task_struct *tsk) { - kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", + kdebug("validate_creds_for_do_exit(%p,%p{%ld,%d})", tsk->real_cred, tsk->cred, - atomic_read(&tsk->cred->usage), + atomic_long_read(&tsk->cred->usage), read_cred_subscribers(tsk->cred));
__validate_process_creds(tsk, __FILE__, __LINE__);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangyu Hua hbh25y@gmail.com
commit 7f8ed28d1401320bcb02dda81b3c23ab2dc5a6d8 upstream.
fuse_dax_conn_free() will be called when fuse_fill_super_common() fails after fuse_dax_conn_alloc(). Then deactivate_locked_super() in virtio_fs_get_tree() will call virtio_kill_sb() to release the discarded superblock. This will call fuse_dax_conn_free() again in fuse_conn_put(), resulting in a possible double free.
Fixes: 1dd539577c42 ("virtiofs: add a mount option to enable dax") Signed-off-by: Hangyu Hua hbh25y@gmail.com Acked-by: Vivek Goyal vgoyal@redhat.com Reviewed-by: Jingbo Xu jefflexu@linux.alibaba.com Cc: stable@vger.kernel.org # v5.10 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/dax.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/fuse/dax.c +++ b/fs/fuse/dax.c @@ -1228,6 +1228,7 @@ void fuse_dax_conn_free(struct fuse_conn if (fc->dax) { fuse_free_dax_mem_ranges(&fc->dax->free_ranges); kfree(fc->dax); + fc->dax = NULL; } }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Vehmanen kai.vehmanen@linux.intel.com
commit 924f5ca2975b2993ee81a7ecc3c809943a70f334 upstream.
On ASUSTeK Z170M PLUS and Z170 PRO GAMING systems, the display codec pins are not registered properly without the force-connect quirk. The codec will report only one pin as having external connectivity, but i915 finds all three connectors on the system, so the two drivers are not in sync.
Issue found with DRM igt-gpu-tools test kms_hdmi_inject@inject-audio.
Link: https://gitlab.freedesktop.org/drm/intel/-/issues/9801 Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Jani Saarinen jani.saarinen@intel.com Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20231208132127.2438067-3-kai.vehmanen@linux.intel.... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_hdmi.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1967,6 +1967,8 @@ static const struct snd_pci_quirk force_ SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), SND_PCI_QUIRK(0x103c, 0x8715, "HP", 1), + SND_PCI_QUIRK(0x1043, 0x86ae, "ASUS", 1), /* Z170 PRO */ + SND_PCI_QUIRK(0x1043, 0x86c7, "ASUS", 1), /* Z170M PLUS */ SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1), {} };
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hartmut Knaack knaack.h@gmx.de
commit 9b726bf6ae11add6a7a52883a21f90ff9cbca916 upstream.
The HP laptop 15-db0403ng uses the ALC236 codec and controls the mute LED using COEF 0x07 index 1. Sound card subsystem: Hewlett-Packard Company Device [103c:84ae]
Use the existing quirk for this model.
Signed-off-by: Hartmut Knaack knaack.h@gmx.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/e61815d0-f1c7-b164-e49d-6ca84771476a@gmx.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8986,6 +8986,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), + SND_PCI_QUIRK(0x103c, 0x84ae, "HP 15-db0403ng", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN), SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjorn Helgaas bhelgaas@google.com
commit 5df12742b7e3aae2594a30a9d14d5d6e9e7699f4 upstream.
This reverts commit 40613da52b13fb21c5566f10b287e0ca8c12c4e9 and the subsequent fix to it:
cc22522fd55e ("PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus")
40613da52b13 fixed a problem where hot-adding a device with large BARs failed if the bridge windows programmed by firmware were not large enough.
cc22522fd55e ("PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus") fixed a problem with 40613da52b13: an ACPI hot-add of a device on a PCI root bus (common in the virt world) or firmware sending ACPI Bus Check to non-existent Root Ports (e.g., on Dell Inspiron 7352/0W6WV0) caused a NULL pointer dereference and suspend/resume hangs.
Unfortunately the combination of 40613da52b13 and cc22522fd55e caused other problems:
- Fiona reported that hot-add of SCSI disks in QEMU virtual machine fails sometimes.
- Dongli reported a similar problem with hot-add of SCSI disks.
- Jonathan reported a console freeze during boot on bare metal due to an error in radeon GPU initialization.
Revert both patches to avoid adding these problems. This means we will again see the problems with hot-adding devices with large BARs and the NULL pointer dereferences and suspend/resume issues that 40613da52b13 and cc22522fd55e were intended to fix.
Fixes: 40613da52b13 ("PCI: acpiphp: Reassign resources on bridge if necessary") Fixes: cc22522fd55e ("PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root bus") Reported-by: Fiona Ebner f.ebner@proxmox.com Closes: https://lore.kernel.org/r/9eb669c0-d8f2-431d-a700-6da13053ae54@proxmox.com Reported-by: Dongli Zhang dongli.zhang@oracle.com Closes: https://lore.kernel.org/r/3c4a446a-b167-11b8-f36f-d3c1b49b42e9@oracle.com Reported-by: Jonathan Woithe jwoithe@just42.net Closes: https://lore.kernel.org/r/ZXpaNCLiDM+Kv38H@marvin.atrad.com.au Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Michael S. Tsirkin mst@redhat.com Acked-by: Igor Mammedov imammedo@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/hotplug/acpiphp_glue.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
--- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -503,15 +503,12 @@ static void enable_slot(struct acpiphp_s if (pass && dev->subordinate) { check_hotplug_bridge(slot, dev); pcibios_resource_survey_bus(dev->subordinate); - if (pci_is_root_bus(bus)) - __pci_bus_size_bridges(dev->subordinate, &add_list); + __pci_bus_size_bridges(dev->subordinate, + &add_list); } } } - if (pci_is_root_bus(bus)) - __pci_bus_assign_resources(bus, &add_list, NULL); - else - pci_assign_unassigned_bridge_resources(bus->self); + __pci_bus_assign_resources(bus, &add_list, NULL); }
acpiphp_sanitize_bus(bus);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiaxun Yang jiaxun.yang@flygoat.com
commit ef61a0405742a9f7f6051bc6fd2f017d87d07911 upstream.
This is a partial revert of 8b3517f88ff2 ("PCI: loongson: Prevent LS7A MRRS increases") for MIPS-based Loongson.
Some MIPS Loongson systems don't support arbitrary Max_Read_Request_Size (MRRS) settings. 8b3517f88ff2 ("PCI: loongson: Prevent LS7A MRRS increases") worked around that by (1) assuming that firmware configured MRRS to the maximum supported value and (2) preventing the PCI core from increasing MRRS.
Unfortunately, some firmware doesn't set that maximum MRRS correctly, which results in devices not being initialized correctly. One symptom, from the Debian report below, is this:
ata4.00: exception Emask 0x0 SAct 0x20000000 SErr 0x0 action 0x6 frozen ata4.00: failed command: WRITE FPDMA QUEUED ata4.00: cmd 61/20:e8:00:f0:e1/00:00:00:00:00/40 tag 29 ncq dma 16384 out res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout) ata4.00: status: { DRDY } ata4: hard resetting link
Limit MRRS to 256 because MIPS Loongson with higher MRRS support is considered rare.
This must be done at device enablement stage because the MRRS setting may get lost if PCI_COMMAND_MASTER on the parent bridge is cleared, and we are only sure parent bridge is enabled at this point.
Fixes: 8b3517f88ff2 ("PCI: loongson: Prevent LS7A MRRS increases") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217680 Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1035587 Link: https://lore.kernel.org/r/20231201115028.84351-1-jiaxun.yang@flygoat.com Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Acked-by: Huacai Chen chenhuacai@loongson.cn Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-loongson.c | 46 ++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-)
--- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -65,13 +65,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LO DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_LPC, system_bus_quirk);
+/* + * Some Loongson PCIe ports have hardware limitations on their Maximum Read + * Request Size. They can't handle anything larger than this. Sane + * firmware will set proper MRRS at boot, so we only need no_inc_mrrs for + * bridges. However, some MIPS Loongson firmware doesn't set MRRS properly, + * so we have to enforce maximum safe MRRS, which is 256 bytes. + */ +#ifdef CONFIG_MIPS +static void loongson_set_min_mrrs_quirk(struct pci_dev *pdev) +{ + struct pci_bus *bus = pdev->bus; + struct pci_dev *bridge; + static const struct pci_device_id bridge_devids[] = { + { PCI_VDEVICE(LOONGSON, DEV_LS2K_PCIE_PORT0) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT0) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT1) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT2) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT3) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT4) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT5) }, + { PCI_VDEVICE(LOONGSON, DEV_LS7A_PCIE_PORT6) }, + { 0, }, + }; + + /* look for the matching bridge */ + while (!pci_is_root_bus(bus)) { + bridge = bus->self; + bus = bus->parent; + + if (pci_match_id(bridge_devids, bridge)) { + if (pcie_get_readrq(pdev) > 256) { + pci_info(pdev, "limiting MRRS to 256\n"); + pcie_set_readrq(pdev, 256); + } + break; + } + } +} +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_set_min_mrrs_quirk); +#endif + static void loongson_mrrs_quirk(struct pci_dev *pdev) { - /* - * Some Loongson PCIe ports have h/w limitations of maximum read - * request size. They can't handle anything larger than this. So - * force this limit on any devices attached under these ports. - */ struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
bridge->no_inc_mrrs = 1;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit f6ebe9f9c9233a6114eb922aba9a0c9ccc2d2e14 ]
The current atomic helpers have either their object state being passed as an argument or the full atomic state.
The former is the pattern that was done at first, before switching to the latter for new hooks or when it was needed.
Let's start convert all the remaining helpers to provide a consistent interface, starting with the CRTC's atomic_begin and atomic_flush.
The conversion was done using the coccinelle script below, built tested on all the drivers and actually tested on vc4.
virtual report
@@ struct drm_crtc_helper_funcs *FUNCS; identifier old_crtc_state, old_state; identifier crtc; identifier f; @@
f(struct drm_crtc_state *old_crtc_state) { ... struct drm_atomic_state *old_state = old_crtc_state->state; <... - FUNCS->atomic_begin(crtc, old_crtc_state); + FUNCS->atomic_begin(crtc, old_state); ...> }
@@ struct drm_crtc_helper_funcs *FUNCS; identifier old_crtc_state, old_state; identifier crtc; identifier f; @@
f(struct drm_crtc_state *old_crtc_state) { ... struct drm_atomic_state *old_state = old_crtc_state->state; <... - FUNCS->atomic_flush(crtc, old_crtc_state); + FUNCS->atomic_flush(crtc, old_state); ...> }
@@ struct drm_crtc_helper_funcs *FUNCS; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; identifier dev, state; identifier f; @@
f(struct drm_device *dev, struct drm_atomic_state *state, ...) { <... - FUNCS->atomic_begin(crtc, crtc_state); + FUNCS->atomic_begin(crtc, state); ...> }
@@ struct drm_crtc_helper_funcs *FUNCS; struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; identifier dev, state; identifier f; @@
f(struct drm_device *dev, struct drm_atomic_state *state, ...) { <... - FUNCS->atomic_flush(crtc, crtc_state); + FUNCS->atomic_flush(crtc, state); ...> }
@@ identifier crtc, old_state; @@
struct drm_crtc_helper_funcs { ... - void (*atomic_begin)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_begin)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... - void (*atomic_flush)(struct drm_crtc *crtc, struct drm_crtc_state *old_state); + void (*atomic_flush)(struct drm_crtc *crtc, struct drm_atomic_state *state); ... }
@ crtc_atomic_func @ identifier helpers; identifier func; @@
( static struct drm_crtc_helper_funcs helpers = { ..., .atomic_begin = func, ..., }; | static struct drm_crtc_helper_funcs helpers = { ..., .atomic_flush = func, ..., }; )
@ ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@
void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { ... when != old_state }
@ adds_old_state depends on crtc_atomic_func && !ignores_old_state @ identifier crtc_atomic_func.func; identifier crtc, old_state; @@
void func(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); ... }
@ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; expression E; type T; @@
void func(...) { ... - T state = E; + T crtc_state = E; <+... - state + crtc_state ...+>
}
@ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; type T; @@
void func(...) { ... - T state; + T crtc_state; <+... - state + crtc_state ...+>
}
@@ identifier old_state; identifier crtc; @@
void vc4_hvs_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, crtc); ... }
@@ identifier old_state; identifier crtc; @@
void vc4_hvs_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state );
@@ identifier old_state; identifier crtc; @@
void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... }
@@ identifier old_state; identifier crtc; @@
void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state );
@@ identifier old_state; identifier crtc; @@
void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... }
@@ identifier old_state; identifier crtc; @@
void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state );
@ depends on crtc_atomic_func @ identifier crtc_atomic_func.func; identifier old_state; identifier crtc; @@
void func(struct drm_crtc *crtc, - struct drm_crtc_state *old_state + struct drm_atomic_state *state ) { ... }
@ include depends on adds_old_state @ @@
#include <drm/drm_atomic.h>
@ no_include depends on !include && adds_old_state @ @@
+ #include <drm/drm_atomic.h> #include <drm/...>
Signed-off-by: Maxime Ripard maxime@cerno.tech Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Acked-by: Daniel Vetter daniel.vetter@ffwll.ch Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20201028123222.1732139-2-maxim... Stable-dep-of: fe4c5f662097 ("drm/mediatek: Add spinlock for setting vblank event in atomic_begin") Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/arm/display/komeda/komeda_crtc.c | 4 +++- drivers/gpu/drm/arm/hdlcd_crtc.c | 2 +- drivers/gpu/drm/armada/armada_crtc.c | 4 ++-- drivers/gpu/drm/ast/ast_mode.c | 5 ++++- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 4 ++-- drivers/gpu/drm/drm_atomic_helper.c | 8 ++++---- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 4 ++-- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 2 +- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c | 4 ++-- drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c | 4 ++-- drivers/gpu/drm/imx/dcss/dcss-crtc.c | 4 ++-- drivers/gpu/drm/imx/ipuv3-crtc.c | 4 ++-- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 17 +++++++++-------- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 16 ++++++++-------- drivers/gpu/drm/meson/meson_crtc.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 4 ++-- drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 4 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 4 ++-- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 2 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 ++-- drivers/gpu/drm/qxl/qxl_display.c | 2 +- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 8 ++++++-- drivers/gpu/drm/sti/sti_crtc.c | 2 +- drivers/gpu/drm/stm/ltdc.c | 2 +- drivers/gpu/drm/sun4i/sun4i_crtc.c | 6 ++++-- drivers/gpu/drm/tegra/dc.c | 10 +++++----- drivers/gpu/drm/tidss/tidss_crtc.c | 4 +++- drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 2 +- drivers/gpu/drm/vboxvideo/vbox_mode.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 3 ++- drivers/gpu/drm/vc4/vc4_hvs.c | 4 +++- drivers/gpu/drm/virtio/virtgpu_display.c | 2 +- drivers/gpu/drm/vkms/vkms_crtc.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 4 ++-- drivers/gpu/drm/xlnx/zynqmp_disp.c | 4 ++-- drivers/gpu/drm/zte/zx_vou.c | 2 +- include/drm/drm_modeset_helper_vtables.h | 4 ++-- 39 files changed, 97 insertions(+), 80 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index f33418d6e1a08..3c77eeb0a7a0c 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -379,8 +379,10 @@ komeda_crtc_atomic_disable(struct drm_crtc *crtc,
static void komeda_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old) + struct drm_atomic_state *state) { + struct drm_crtc_state *old = drm_atomic_get_old_crtc_state(state, + crtc); /* commit with modeset will be handled in enable/disable */ if (drm_atomic_crtc_needs_modeset(crtc->state)) return; diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index af67fefed38dc..bd17646f4e133 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -205,7 +205,7 @@ static enum drm_mode_status hdlcd_crtc_mode_valid(struct drm_crtc *crtc, }
static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_atomic_state *state) { struct drm_pending_vblank_event *event = crtc->state->event;
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index a887b6a5f8bd7..13c7c474fb26e 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -427,7 +427,7 @@ static int armada_drm_crtc_atomic_check(struct drm_crtc *crtc, }
static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
@@ -441,7 +441,7 @@ static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc, }
static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index d27f2840b9555..84c2e90d415f4 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -777,8 +777,11 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, }
static void -ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) +ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct ast_private *ast = to_ast_private(crtc->dev); struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state); struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index ce246b96330b7..e7064abfa66ef 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -341,7 +341,7 @@ static int atmel_hlcdc_crtc_atomic_check(struct drm_crtc *c, }
static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c, - struct drm_crtc_state *old_s) + struct drm_atomic_state *state) { struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c);
@@ -356,7 +356,7 @@ static void atmel_hlcdc_crtc_atomic_begin(struct drm_crtc *c, }
static void atmel_hlcdc_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_s) + struct drm_atomic_state *state) { /* TODO: write common plane control register if available */ } diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 0fde260b7edd8..121947e570e97 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2526,7 +2526,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (active_only && !new_crtc_state->active) continue;
- funcs->atomic_begin(crtc, old_crtc_state); + funcs->atomic_begin(crtc, old_state); }
for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) { @@ -2584,7 +2584,7 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, if (active_only && !new_crtc_state->active) continue;
- funcs->atomic_flush(crtc, old_crtc_state); + funcs->atomic_flush(crtc, old_state); } } EXPORT_SYMBOL(drm_atomic_helper_commit_planes); @@ -2622,7 +2622,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
crtc_funcs = crtc->helper_private; if (crtc_funcs && crtc_funcs->atomic_begin) - crtc_funcs->atomic_begin(crtc, old_crtc_state); + crtc_funcs->atomic_begin(crtc, old_state);
drm_for_each_plane_mask(plane, crtc->dev, plane_mask) { struct drm_plane_state *old_plane_state = @@ -2648,7 +2648,7 @@ drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state) }
if (crtc_funcs && crtc_funcs->atomic_flush) - crtc_funcs->atomic_flush(crtc, old_crtc_state); + crtc_funcs->atomic_flush(crtc, old_state); } EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index de9fadccf22e5..3043f49c70f0c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -62,7 +62,7 @@ static int exynos_crtc_atomic_check(struct drm_crtc *crtc, }
static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
@@ -71,7 +71,7 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, }
static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c index b9ca81a6f80fb..9cd0c5c35af96 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c @@ -21,7 +21,7 @@ #include "fsl_dcu_drm_plane.h"
static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct drm_device *dev = crtc->dev; struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index 4d57ec688f827..222a895a3608e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -393,7 +393,7 @@ static void hibmc_crtc_mode_set_nofb(struct drm_crtc *crtc) }
static void hibmc_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { unsigned int reg; struct drm_device *dev = crtc->dev; @@ -413,7 +413,7 @@ static void hibmc_crtc_atomic_begin(struct drm_crtc *crtc, }
static void hibmc_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state)
{ unsigned long flags; diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index e1108c1735ad0..32d3cc89dbe93 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -485,7 +485,7 @@ static void ade_crtc_mode_set_nofb(struct drm_crtc *crtc) }
static void ade_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct kirin_crtc *kcrtc = to_kirin_crtc(crtc); struct ade_hw_ctx *ctx = kcrtc->hw_ctx; @@ -498,7 +498,7 @@ static void ade_crtc_atomic_begin(struct drm_crtc *crtc, }
static void ade_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state)
{ struct kirin_crtc *kcrtc = to_kirin_crtc(crtc); diff --git a/drivers/gpu/drm/imx/dcss/dcss-crtc.c b/drivers/gpu/drm/imx/dcss/dcss-crtc.c index 36abff0890b28..98fb71ca06695 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-crtc.c +++ b/drivers/gpu/drm/imx/dcss/dcss-crtc.c @@ -52,13 +52,13 @@ static const struct drm_crtc_funcs dcss_crtc_funcs = { };
static void dcss_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { drm_crtc_vblank_on(crtc); }
static void dcss_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct dcss_crtc *dcss_crtc = container_of(crtc, struct dcss_crtc, base); diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index fd9d8e51837fa..cf1e39f83401f 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -236,13 +236,13 @@ static int ipu_crtc_atomic_check(struct drm_crtc *crtc, }
static void ipu_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { drm_crtc_vblank_on(crtc); }
static void ipu_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { spin_lock_irq(&crtc->dev->event_lock); if (crtc->state->event) { diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 5ec9770e401e4..6d56b701118da 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -287,7 +287,7 @@ ingenic_drm_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode }
static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *oldstate) + struct drm_atomic_state *state) { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); u32 ctrl = 0; @@ -307,26 +307,27 @@ static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc, }
static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *oldstate) + struct drm_atomic_state *state) { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); - struct drm_crtc_state *state = crtc->state; - struct drm_pending_vblank_event *event = state->event; + struct drm_crtc_state *crtc_state = crtc->state; + struct drm_pending_vblank_event *event = crtc_state->event;
- if (drm_atomic_crtc_needs_modeset(state)) { - ingenic_drm_crtc_update_timings(priv, &state->mode); + if (drm_atomic_crtc_needs_modeset(crtc_state)) { + ingenic_drm_crtc_update_timings(priv, &crtc_state->mode); priv->update_clk_rate = true; }
if (priv->update_clk_rate) { mutex_lock(&priv->clk_mutex); - clk_set_rate(priv->pix_clk, state->adjusted_mode.clock * 1000); + clk_set_rate(priv->pix_clk, + crtc_state->adjusted_mode.clock * 1000); priv->update_clk_rate = false; mutex_unlock(&priv->clk_mutex); }
if (event) { - state->event = NULL; + crtc_state->event = NULL;
spin_lock_irq(&crtc->dev->event_lock); if (drm_crtc_vblank_get(crtc) == 0) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index cc3cb5b63d444..067b4dc39f4f0 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -578,24 +578,24 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, }
static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { - struct mtk_crtc_state *state = to_mtk_crtc_state(crtc->state); + struct mtk_crtc_state *crtc_state = to_mtk_crtc_state(crtc->state); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- if (mtk_crtc->event && state->base.event) + if (mtk_crtc->event && crtc_state->base.event) DRM_ERROR("new event while there is still a pending event\n");
- if (state->base.event) { - state->base.event->pipe = drm_crtc_index(crtc); + if (crtc_state->base.event) { + crtc_state->base.event->pipe = drm_crtc_index(crtc); WARN_ON(drm_crtc_vblank_get(crtc) != 0); - mtk_crtc->event = state->base.event; - state->base.event = NULL; + mtk_crtc->event = crtc_state->base.event; + crtc_state->base.event = NULL; } }
static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); int i; diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c index 2854272dc2d9b..c7f7bb160bba4 100644 --- a/drivers/gpu/drm/meson/meson_crtc.c +++ b/drivers/gpu/drm/meson/meson_crtc.c @@ -201,7 +201,7 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc, }
static void meson_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); unsigned long flags; @@ -217,7 +217,7 @@ static void meson_crtc_atomic_begin(struct drm_crtc *crtc, }
static void meson_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct meson_crtc *meson_crtc = to_meson_crtc(crtc); struct meson_drm *priv = meson_crtc->priv; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 4c64e2d4f6500..108911a43f92b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -485,7 +485,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) }
static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct drm_encoder *encoder; @@ -526,7 +526,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, }
static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct dpu_crtc *dpu_crtc; struct drm_device *dev; diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c index a0253297bc769..69ac1eee1a227 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -316,14 +316,14 @@ static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, }
static void mdp4_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); DBG("%s: begin", mdp4_crtc->name); }
static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct drm_device *dev = crtc->dev; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 60e7371cd0e0d..077369989a04b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -775,13 +775,13 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, }
static void mdp5_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { DBG("%s: begin", crtc->name); }
static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state); diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index b535621f4f78d..d0e9d0ae9951f 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -324,7 +324,7 @@ static int mxsfb_crtc_atomic_check(struct drm_crtc *crtc, }
static void mxsfb_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_pending_vblank_event *event;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 328a4a74f534e..3bc060682dcdc 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -598,12 +598,12 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, }
static void omap_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { }
static void omap_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct omap_drm_private *priv = crtc->dev->dev_private; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index f22a1b776f4ba..26294016f1e39 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -373,7 +373,7 @@ static void qxl_crtc_update_monitors_config(struct drm_crtc *crtc, }
static void qxl_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { qxl_crtc_update_monitors_config(crtc, "flush"); } diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 065604c5837de..7007a8120394e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -780,7 +780,7 @@ static void rcar_du_crtc_atomic_disable(struct drm_crtc *crtc, }
static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
@@ -809,7 +809,7 @@ static void rcar_du_crtc_atomic_begin(struct drm_crtc *crtc, }
static void rcar_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); struct drm_device *dev = rcrtc->crtc.dev; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 682d78fab9a59..b7eeb3183aa94 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1255,8 +1255,10 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc, }
static void vop_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct vop *vop = to_vop(crtc);
/* @@ -1467,8 +1469,10 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc, }
static void vop_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_atomic_state *old_state = old_crtc_state->state; struct drm_plane_state *old_plane_state, *new_plane_state; struct vop *vop = to_vop(crtc); diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index 6f37c104c46f9..4f1e22933f48b 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c @@ -133,7 +133,7 @@ sti_crtc_mode_set_nofb(struct drm_crtc *crtc) }
static void sti_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct drm_device *drm_dev = crtc->dev; struct sti_mixer *mixer = to_sti_mixer(crtc); diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 089c00a8e7d49..ae73b93a14612 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -629,7 +629,7 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) }
static void ltdc_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct ltdc_device *ldev = crtc_to_ltdc(crtc); struct drm_device *ddev = crtc->dev; diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 3a153648b3698..cab86ec070843 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -58,8 +58,10 @@ static int sun4i_crtc_atomic_check(struct drm_crtc *crtc, }
static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct drm_device *dev = crtc->dev; struct sunxi_engine *engine = scrtc->engine; @@ -79,7 +81,7 @@ static void sun4i_crtc_atomic_begin(struct drm_crtc *crtc, }
static void sun4i_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); struct drm_pending_vblank_event *event = crtc->state->event; diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 958d12da902d3..f1e8951fa86c4 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1924,7 +1924,7 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc, }
static void tegra_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { unsigned long flags;
@@ -1943,17 +1943,17 @@ static void tegra_crtc_atomic_begin(struct drm_crtc *crtc, }
static void tegra_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { - struct tegra_dc_state *state = to_dc_state(crtc->state); + struct tegra_dc_state *crtc_state = to_dc_state(crtc->state); struct tegra_dc *dc = to_tegra_dc(crtc); u32 value;
- value = state->planes << 8 | GENERAL_UPDATE; + value = crtc_state->planes << 8 | GENERAL_UPDATE; tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
- value = state->planes | GENERAL_ACT_REQ; + value = crtc_state->planes | GENERAL_ACT_REQ; tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); } diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index 3c5744a91d4a0..7f80496173e85 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -161,8 +161,10 @@ static void tidss_crtc_position_planes(struct tidss_device *tidss, }
static void tidss_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, + crtc); struct tidss_crtc *tcrtc = to_tidss_crtc(crtc); struct drm_device *ddev = crtc->dev; struct tidss_device *tidss = to_tidss(ddev); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 0aaa4a26b5db5..bf8587c24dfe7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c @@ -547,7 +547,7 @@ static void tilcdc_crtc_atomic_disable(struct drm_crtc *crtc, }
static void tilcdc_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { if (!crtc->state->event) return; diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index 4fcc0a542b8a6..ce173baaa84b6 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -223,7 +223,7 @@ static void vbox_crtc_atomic_disable(struct drm_crtc *crtc, }
static void vbox_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { }
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 921463625d82e..5d1e6a8323bf2 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -919,7 +919,8 @@ int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output); int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state); void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state); void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state); -void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *state); +void vc4_hvs_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_state *state); void vc4_hvs_dump_state(struct drm_device *dev); void vc4_hvs_unmask_underrun(struct drm_device *dev, int channel); void vc4_hvs_mask_underrun(struct drm_device *dev, int channel); diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index f8f2fc3d15f73..34c342968e49e 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -414,8 +414,10 @@ void vc4_hvs_atomic_disable(struct drm_crtc *crtc, }
void vc4_hvs_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { + struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, + crtc); struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 9b2b99e853422..fcbb0a6cdb173 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -117,7 +117,7 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, }
static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 1ae5cd47d9546..252b7e0ba58e8 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -227,7 +227,7 @@ static void vkms_crtc_atomic_disable(struct drm_crtc *crtc, }
static void vkms_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc);
@@ -238,7 +238,7 @@ static void vkms_crtc_atomic_begin(struct drm_crtc *crtc, }
static void vkms_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct vkms_output *vkms_output = drm_crtc_to_vkms_output(crtc);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0e963fd7db17e..0d5da0a1b506a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -553,13 +553,13 @@ int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { }
void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { struct drm_pending_vblank_event *event = crtc->state->event;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 3ee03227607c6..d49b1c741b6b1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -475,9 +475,9 @@ void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps, int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state); void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); void vmw_du_crtc_reset(struct drm_crtc *crtc); struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc); void vmw_du_crtc_destroy_state(struct drm_crtc *crtc, diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 205c72a249b75..227449ca017ee 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1511,14 +1511,14 @@ static int zynqmp_disp_crtc_atomic_check(struct drm_crtc *crtc,
static void zynqmp_disp_crtc_atomic_begin(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { drm_crtc_vblank_on(crtc); }
static void zynqmp_disp_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state) + struct drm_atomic_state *state) { if (crtc->state->event) { struct drm_pending_vblank_event *event; diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c index 5259ff2825f94..d91563a2603a8 100644 --- a/drivers/gpu/drm/zte/zx_vou.c +++ b/drivers/gpu/drm/zte/zx_vou.c @@ -473,7 +473,7 @@ static void zx_crtc_atomic_disable(struct drm_crtc *crtc, }
static void zx_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) + struct drm_atomic_state *state) { struct drm_pending_vblank_event *event = crtc->state->event;
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 4efec30f8badc..e4b645f5b04a1 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -374,7 +374,7 @@ struct drm_crtc_helper_funcs { * transitional plane helpers, but it is optional. */ void (*atomic_begin)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state); /** * @atomic_flush: * @@ -398,7 +398,7 @@ struct drm_crtc_helper_funcs { * transitional plane helpers, but it is optional. */ void (*atomic_flush)(struct drm_crtc *crtc, - struct drm_crtc_state *old_crtc_state); + struct drm_atomic_state *state);
/** * @atomic_enable:
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 253f28b6237264216b052ac0848fd7fc917b5259 ]
Many drivers reference the crtc->pointer in order to get the current CRTC state in their atomic_begin or atomic_flush hooks, which would be the new CRTC state in the global atomic state since _swap_state happened when those hooks are run.
Use the drm_atomic_get_new_crtc_state helper to get that state to make it more obvious.
This was made using the coccinelle script below:
@ crtc_atomic_func @ identifier helpers; identifier func; @@
( static struct drm_crtc_helper_funcs helpers = { ..., .atomic_begin = func, ..., }; | static struct drm_crtc_helper_funcs helpers = { ..., .atomic_flush = func, ..., }; )
@@ identifier crtc_atomic_func.func; identifier crtc, state; symbol crtc_state; expression e; @@
func(struct drm_crtc *crtc, struct drm_atomic_state *state) { ... - struct tegra_dc_state *crtc_state = e; + struct tegra_dc_state *dc_state = e; <+... - crtc_state + dc_state ...+> }
@@ identifier crtc_atomic_func.func; identifier crtc, state; symbol crtc_state; expression e; @@
func(struct drm_crtc *crtc, struct drm_atomic_state *state) { ... - struct mtk_crtc_state *crtc_state = e; + struct mtk_crtc_state *mtk_crtc_state = e; <+... - crtc_state + mtk_crtc_state ...+> }
@ replaces_new_state @ identifier crtc_atomic_func.func; identifier crtc, state, crtc_state; @@
func(struct drm_crtc *crtc, struct drm_atomic_state *state) { ... - struct drm_crtc_state *crtc_state = crtc->state; + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ... }
@@ identifier crtc_atomic_func.func; identifier crtc, state, crtc_state; @@
func(struct drm_crtc *crtc, struct drm_atomic_state *state) { struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ... - crtc->state + crtc_state ... }
@ adds_new_state @ identifier crtc_atomic_func.func; identifier crtc, state; @@
func(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); ... - crtc->state + crtc_state ... }
@ include depends on adds_new_state || replaces_new_state @ @@
#include <drm/drm_atomic.h>
@ no_include depends on !include && (adds_new_state || replaces_new_state) @ @@
+ #include <drm/drm_atomic.h> #include <drm/...>
Suggested-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Maxime Ripard maxime@cerno.tech Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Acked-by: Thomas Zimmermann tzimmermann@suse.de Cc: "James (Qian) Wang" james.qian.wang@arm.com Cc: Liviu Dudau liviu.dudau@arm.com Cc: Mihail Atanassov mihail.atanassov@arm.com Cc: Brian Starkey brian.starkey@arm.com Cc: Russell King linux@armlinux.org.uk Cc: Paul Cercueil paul@crapouillou.net Cc: Chun-Kuang Hu chunkuang.hu@kernel.org Cc: Philipp Zabel p.zabel@pengutronix.de Cc: Sandy Huang hjc@rock-chips.com Cc: "Heiko Stübner" heiko@sntech.de Cc: Thierry Reding thierry.reding@gmail.com Cc: Gerd Hoffmann kraxel@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20201105164518.392891-1-maxime... Stable-dep-of: fe4c5f662097 ("drm/mediatek: Add spinlock for setting vblank event in atomic_begin") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 4 +++- drivers/gpu/drm/armada/armada_crtc.c | 8 ++++++-- drivers/gpu/drm/ast/ast_mode.c | 4 +++- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 7 +++++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 15 +++++++++------ drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 6 ++++-- drivers/gpu/drm/tegra/dc.c | 8 +++++--- drivers/gpu/drm/virtio/virtgpu_display.c | 4 +++- 8 files changed, 38 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 3c77eeb0a7a0c..db995250cbff6 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -381,10 +381,12 @@ static void komeda_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct drm_crtc_state *old = drm_atomic_get_old_crtc_state(state, crtc); /* commit with modeset will be handled in enable/disable */ - if (drm_atomic_crtc_needs_modeset(crtc->state)) + if (drm_atomic_crtc_needs_modeset(crtc_state)) return;
komeda_crtc_do_flush(crtc, old); diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 13c7c474fb26e..8b7cc7bc81ee4 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -429,11 +429,13 @@ static int armada_drm_crtc_atomic_check(struct drm_crtc *crtc, static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
- if (crtc->state->color_mgmt_changed) + if (crtc_state->color_mgmt_changed) armada_drm_update_gamma(crtc);
dcrtc->regs_idx = 0; @@ -443,6 +445,8 @@ static void armada_drm_crtc_atomic_begin(struct drm_crtc *crtc, static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc);
DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); @@ -453,7 +457,7 @@ static void armada_drm_crtc_atomic_flush(struct drm_crtc *crtc, * If we aren't doing a full modeset, then we need to queue * the event here. */ - if (!drm_atomic_crtc_needs_modeset(crtc->state)) { + if (!drm_atomic_crtc_needs_modeset(crtc_state)) { dcrtc->update_pending = true; armada_drm_crtc_queue_state_event(crtc); spin_lock_irq(&dcrtc->irq_lock); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 84c2e90d415f4..7f3f961035872 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -780,10 +780,12 @@ static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); struct ast_private *ast = to_ast_private(crtc->dev); - struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state); + struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
/* diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 6d56b701118da..784a91d32bd1e 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -289,11 +289,13 @@ ingenic_drm_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct ingenic_drm *priv = drm_crtc_get_priv(crtc); u32 ctrl = 0;
if (priv->soc_info->has_osd && - drm_atomic_crtc_needs_modeset(crtc->state)) { + drm_atomic_crtc_needs_modeset(crtc_state)) { /* * If IPU plane is enabled, enable IPU as source for the F1 * plane; otherwise use regular DMA. @@ -310,7 +312,8 @@ static void ingenic_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { struct ingenic_drm *priv = drm_crtc_get_priv(crtc); - struct drm_crtc_state *crtc_state = crtc->state; + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct drm_pending_vblank_event *event = crtc_state->event;
if (drm_atomic_crtc_needs_modeset(crtc_state)) { diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 067b4dc39f4f0..380b0b52d2c7a 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -11,6 +11,7 @@ #include <asm/barrier.h> #include <soc/mediatek/smi.h>
+#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -580,17 +581,19 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc, static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { - struct mtk_crtc_state *crtc_state = to_mtk_crtc_state(crtc->state); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); + struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
- if (mtk_crtc->event && crtc_state->base.event) + if (mtk_crtc->event && mtk_crtc_state->base.event) DRM_ERROR("new event while there is still a pending event\n");
- if (crtc_state->base.event) { - crtc_state->base.event->pipe = drm_crtc_index(crtc); + if (mtk_crtc_state->base.event) { + mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc); WARN_ON(drm_crtc_vblank_get(crtc) != 0); - mtk_crtc->event = crtc_state->base.event; - crtc_state->base.event = NULL; + mtk_crtc->event = mtk_crtc_state->base.event; + mtk_crtc_state->base.event = NULL; } }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index b7eeb3183aa94..0a20fe4200b3d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1257,6 +1257,8 @@ static void vop_crtc_gamma_set(struct vop *vop, struct drm_crtc *crtc, static void vop_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); struct vop *vop = to_vop(crtc); @@ -1265,8 +1267,8 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc, * Only update GAMMA if the 'active' flag is not changed, * otherwise it's updated by .atomic_enable. */ - if (crtc->state->color_mgmt_changed && - !crtc->state->active_changed) + if (crtc_state->color_mgmt_changed && + !crtc_state->active_changed) vop_crtc_gamma_set(vop, crtc, old_crtc_state); }
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index f1e8951fa86c4..093ac01ac3d90 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1945,15 +1945,17 @@ static void tegra_crtc_atomic_begin(struct drm_crtc *crtc, static void tegra_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { - struct tegra_dc_state *crtc_state = to_dc_state(crtc->state); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); + struct tegra_dc_state *dc_state = to_dc_state(crtc_state); struct tegra_dc *dc = to_tegra_dc(crtc); u32 value;
- value = crtc_state->planes << 8 | GENERAL_UPDATE; + value = dc_state->planes << 8 | GENERAL_UPDATE; tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
- value = crtc_state->planes | GENERAL_ACT_REQ; + value = dc_state->planes | GENERAL_ACT_REQ; tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL); } diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index fcbb0a6cdb173..9af912fc2426b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -119,6 +119,8 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc, static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state) { + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, + crtc); struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
/* @@ -127,7 +129,7 @@ static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc, * in the plane update callback, and here we just check * whenever we must force the modeset. */ - if (drm_atomic_crtc_needs_modeset(crtc->state)) { + if (drm_atomic_crtc_needs_modeset(crtc_state)) { output->needs_modeset = true; } }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason-JH.Lin jason-jh.lin@mediatek.com
[ Upstream commit fe4c5f662097978b6c91c23a13c24ed92339a180 ]
Add spinlock protection to avoid race condition on vblank event between mtk_drm_crtc_atomic_begin() and mtk_drm_finish_page_flip().
Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.") Signed-off-by: Jason-JH.Lin jason-jh.lin@mediatek.com Suggested-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Alexandre Mergnat amergnat@baylibre.com Reviewed-by: Fei Shao fshao@chromium.org Tested-by: Fei Shao fshao@chromium.org Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: CK Hu ck.hu@mediatek.com Link: https://patchwork.kernel.org/project/dri-devel/patch/20230920090658.31181-1-... Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index 380b0b52d2c7a..46ad9ce993f10 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -585,6 +585,7 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, crtc); struct mtk_crtc_state *mtk_crtc_state = to_mtk_crtc_state(crtc_state); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + unsigned long flags;
if (mtk_crtc->event && mtk_crtc_state->base.event) DRM_ERROR("new event while there is still a pending event\n"); @@ -592,7 +593,11 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc, if (mtk_crtc_state->base.event) { mtk_crtc_state->base.event->pipe = drm_crtc_index(crtc); WARN_ON(drm_crtc_vblank_get(crtc) != 0); + + spin_lock_irqsave(&crtc->dev->event_lock, flags); mtk_crtc->event = mtk_crtc_state->base.event; + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + mtk_crtc_state->base.event = NULL; } }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
[ Upstream commit ccab434e674ca95d483788b1895a70c21b7f016a ]
If a device sends a packet that is inbetween 0 and sizeof(u64) the value passed to skb_trim() as length will wrap around ending up as some very large value.
The driver will then proceed to parse the header located at that position, which will either oops or process some random value.
The fix is to check against sizeof(u64) rather than 0, which the driver currently does. The issue exists since the introduction of the driver.
Signed-off-by: Oliver Neukum oneukum@suse.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/aqc111.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index c9c4095181744..4ea02116be182 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -1079,17 +1079,17 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb) u16 pkt_count = 0; u64 desc_hdr = 0; u16 vlan_tag = 0; - u32 skb_len = 0; + u32 skb_len;
if (!skb) goto err;
- if (skb->len == 0) + skb_len = skb->len; + if (skb_len < sizeof(desc_hdr)) goto err;
- skb_len = skb->len; /* RX Descriptor Header */ - skb_trim(skb, skb->len - sizeof(desc_hdr)); + skb_trim(skb, skb_len - sizeof(desc_hdr)); desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb));
/* Check these packets */
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 27b13e209ddca5979847a1b57890e0372c1edcee ]
Inside blkg_for_each_descendant_pre(), both css_for_each_descendant_pre() and blkg_lookup() requires RCU read lock, and either cgroup_assert_mutex_or_rcu_locked() or rcu_read_lock_held() is called.
Fix the warning by adding rcu read lock.
Reported-by: Changhui Zhong czhong@redhat.com Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20231117023527.3188627-2-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-throttle.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index c526fdd0a7b90..4bf514a7bd82c 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -1409,6 +1409,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE), tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE));
+ rcu_read_lock(); /* * Update has_rules[] flags for the updated tg's subtree. A tg is * considered to have rules if either the tg itself or any of its @@ -1436,6 +1437,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) this_tg->latency_target = max(this_tg->latency_target, parent_tg->latency_target); } + rcu_read_unlock();
/* * We're already holding queue_lock and know @tg is valid. Let's
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coly Li colyli@suse.de
[ Upstream commit baf8fb7e0e5ec54ea0839f0c534f2cdcd79bea9c ]
Arraies bcache->stripe_sectors_dirty and bcache->full_dirty_stripes are used for dirty data writeback, their sizes are decided by backing device capacity and stripe size. Larger backing device capacity or smaller stripe size make these two arraies occupies more dynamic memory space.
Currently bcache->stripe_size is directly inherited from queue->limits.io_opt of underlying storage device. For normal hard drives, its limits.io_opt is 0, and bcache sets the corresponding stripe_size to 1TB (1<<31 sectors), it works fine 10+ years. But for devices do declare value for queue->limits.io_opt, small stripe_size (comparing to 1TB) becomes an issue for oversize memory allocations of bcache->stripe_sectors_dirty and bcache->full_dirty_stripes, while the capacity of hard drives gets much larger in recent decade.
For example a raid5 array assembled by three 20TB hardrives, the raid device capacity is 40TB with typical 512KB limits.io_opt. After the math calculation in bcache code, these two arraies will occupy 400MB dynamic memory. Even worse Andrea Tomassetti reports that a 4KB limits.io_opt is declared on a new 2TB hard drive, then these two arraies request 2GB and 512MB dynamic memory from kzalloc(). The result is that bcache device always fails to initialize on his system.
To avoid the oversize memory allocation, bcache->stripe_size should not directly inherited by queue->limits.io_opt from the underlying device. This patch defines BCH_MIN_STRIPE_SZ (4MB) as minimal bcache stripe size and set bcache device's stripe size against the declared limits.io_opt value from the underlying storage device, - If the declared limits.io_opt > BCH_MIN_STRIPE_SZ, bcache device will set its stripe size directly by this limits.io_opt value. - If the declared limits.io_opt < BCH_MIN_STRIPE_SZ, bcache device will set its stripe size by a value multiplying limits.io_opt and euqal or large than BCH_MIN_STRIPE_SZ.
Then the minimal stripe size of a bcache device will always be >= 4MB. For a 40TB raid5 device with 512KB limits.io_opt, memory occupied by bcache->stripe_sectors_dirty and bcache->full_dirty_stripes will be 50MB in total. For a 2TB hard drive with 4KB limits.io_opt, memory occupied by these two arraies will be 2.5MB in total.
Such mount of memory allocated for bcache->stripe_sectors_dirty and bcache->full_dirty_stripes is reasonable for most of storage devices.
Reported-by: Andrea Tomassetti andrea.tomassetti-opensource@devo.com Signed-off-by: Coly Li colyli@suse.de Reviewed-by: Eric Wheeler bcache@lists.ewheeler.net Link: https://lore.kernel.org/r/20231120052503.6122-2-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/bcache.h | 1 + drivers/md/bcache/super.c | 2 ++ 2 files changed, 3 insertions(+)
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index e8bf4f752e8be..5804a8e6e215a 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -265,6 +265,7 @@ struct bcache_device { #define BCACHE_DEV_WB_RUNNING 3 #define BCACHE_DEV_RATE_DW_RUNNING 4 int nr_stripes; +#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT) unsigned int stripe_size; atomic_t *stripe_sectors_dirty; unsigned long *full_dirty_stripes; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index e8c8077667f9e..9c3e1632568c3 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -917,6 +917,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
if (!d->stripe_size) d->stripe_size = 1 << 31; + else if (d->stripe_size < BCH_MIN_STRIPE_SZ) + d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size);
n = DIV_ROUND_UP_ULL(sectors, d->stripe_size); if (!n || n > max_stripes) {
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit be93825f0e6428c2d3f03a6e4d447dc48d33d7ff ]
Variable cur_idx is being initialized with a value that is never read, it is being re-assigned later in a while-loop. Remove the redundant assignment. Cleans up clang scan build warning:
drivers/md/bcache/writeback.c:916:2: warning: Value stored to 'cur_idx' is never read [deadcode.DeadStores]
Signed-off-by: Colin Ian King colin.i.king@gmail.com Reviewed-by: Coly Li colyli@suse.de Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20231120052503.6122-4-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/writeback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 94e899ce38554..8e3f5f004c397 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -857,7 +857,7 @@ static int bch_dirty_init_thread(void *arg) int cur_idx, prev_idx, skip_nr;
k = p = NULL; - cur_idx = prev_idx = 0; + prev_idx = 0;
bch_btree_iter_init(&c->root->keys, &iter, NULL); k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coly Li colyli@suse.de
[ Upstream commit 31f5b956a197d4ec25c8a07cb3a2ab69d0c0b82f ]
This patch adds code comments to bch_btree_node_get() and __bch_btree_node_alloc() that NULL pointer will not be returned and it is unnecessary to check NULL pointer by the callers of these routines.
Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20231120052503.6122-10-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/btree.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 3d6a7fbcbb15e..1a1a9554474ae 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -974,6 +974,9 @@ static struct btree *mca_alloc(struct cache_set *c, struct btree_op *op, * * The btree node will have either a read or a write lock held, depending on * level and op->lock. + * + * Note: Only error code or btree pointer will be returned, it is unncessary + * for callers to check NULL pointer. */ struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, struct bkey *k, int level, bool write, @@ -1085,6 +1088,10 @@ static void btree_node_free(struct btree *b) mutex_unlock(&b->c->bucket_lock); }
+/* + * Only error code or btree pointer will be returned, it is unncessary for + * callers to check NULL pointer. + */ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, int level, bool wait, struct btree *parent)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Coly Li colyli@suse.de
[ Upstream commit 3eba5e0b2422aec3c9e79822029599961fdcab97 ]
In run_cache_set() after c->root returned from bch_btree_node_get(), it is checked by IS_ERR_OR_NULL(). Indeed it is unncessary to check NULL because bch_btree_node_get() will not return NULL pointer to caller.
This patch replaces IS_ERR_OR_NULL() by IS_ERR() for the above reason.
Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20231120052503.6122-11-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 9c3e1632568c3..04ddaa4bbd77f 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -2043,7 +2043,7 @@ static int run_cache_set(struct cache_set *c) c->root = bch_btree_node_get(c, NULL, k, j->btree_level, true, NULL); - if (IS_ERR_OR_NULL(c->root)) + if (IS_ERR(c->root)) goto err;
list_del_init(&c->root->list);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit a6584711e64d9d12ab79a450ec3628fd35e4f476 ]
LKP found issues with a kernel doc in the driver:
core.c:116: warning: Function parameter or member 'ioss_evtconfig' not described in 'telemetry_update_events' core.c:188: warning: Function parameter or member 'ioss_evtconfig' not described in 'telemetry_get_eventconfig'
It looks like it were copy'n'paste typos when these descriptions had been introduced. Fix the typos.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202310070743.WALmRGSY-lkp@intel.com/ Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20231120150756.1661425-1-andriy.shevchenko@linux.i... Reviewed-by: Rajneesh Bhardwaj irenic.rajneesh@gmail.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel_telemetry_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/intel_telemetry_core.c b/drivers/platform/x86/intel_telemetry_core.c index fdf55b5d69480..e4be40f73eebf 100644 --- a/drivers/platform/x86/intel_telemetry_core.c +++ b/drivers/platform/x86/intel_telemetry_core.c @@ -102,7 +102,7 @@ static const struct telemetry_core_ops telm_defpltops = { /** * telemetry_update_events() - Update telemetry Configuration * @pss_evtconfig: PSS related config. No change if num_evts = 0. - * @pss_evtconfig: IOSS related config. No change if num_evts = 0. + * @ioss_evtconfig: IOSS related config. No change if num_evts = 0. * * This API updates the IOSS & PSS Telemetry configuration. Old config * is overwritten. Call telemetry_reset_events when logging is over @@ -176,7 +176,7 @@ EXPORT_SYMBOL_GPL(telemetry_reset_events); /** * telemetry_get_eventconfig() - Returns the pss and ioss events enabled * @pss_evtconfig: Pointer to PSS related configuration. - * @pss_evtconfig: Pointer to IOSS related configuration. + * @ioss_evtconfig: Pointer to IOSS related configuration. * @pss_len: Number of u32 elements allocated for pss_evtconfig array * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array *
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brett Raye braye@fastmail.com
[ Upstream commit a5e913c25b6b2b6ae02acef6d9400645ac03dfdf ]
The Glorious Model I mouse has a buggy HID report descriptor for its keyboard endpoint (used for programmable buttons). For report ID 2, there is a mismatch between Logical Minimum and Usage Minimum in the array that reports keycodes.
The offending portion of the descriptor: (from hid-decode)
0x95, 0x05, // Report Count (5) 30 0x75, 0x08, // Report Size (8) 32 0x15, 0x00, // Logical Minimum (0) 34 0x25, 0x65, // Logical Maximum (101) 36 0x05, 0x07, // Usage Page (Keyboard) 38 0x19, 0x01, // Usage Minimum (1) 40 0x29, 0x65, // Usage Maximum (101) 42 0x81, 0x00, // Input (Data,Arr,Abs) 44
This bug shifts all programmed keycodes up by 1. Importantly, this causes "empty" array indexes of 0x00 to be interpreted as 0x01, ErrorRollOver. The presence of ErrorRollOver causes the system to ignore all keypresses from the endpoint and breaks the ability to use the programmable buttons.
Setting byte 41 to 0x00 fixes this, and causes keycodes to be interpreted correctly.
Also, USB_VENDOR_ID_GLORIOUS is changed to USB_VENDOR_ID_SINOWEALTH, and a new ID for Laview Technology is added. Glorious seems to be white-labeling controller boards or mice from these vendors. There isn't a single canonical vendor ID for Glorious products.
Signed-off-by: Brett Raye braye@fastmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-glorious.c | 16 ++++++++++++++-- drivers/hid/hid-ids.h | 11 +++++++---- 2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-glorious.c b/drivers/hid/hid-glorious.c index 558eb08c19ef9..281b3a7187cec 100644 --- a/drivers/hid/hid-glorious.c +++ b/drivers/hid/hid-glorious.c @@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice"); * Glorious Model O and O- specify the const flag in the consumer input * report descriptor, which leads to inputs being ignored. Fix this * by patching the descriptor. + * + * Glorious Model I incorrectly specifes the Usage Minimum for its + * keyboard HID report, causing keycodes to be misinterpreted. + * Fix this by setting Usage Minimum to 0 in that report. */ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) @@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[85] = rdesc[113] = rdesc[141] = \ HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE; } + if (*rsize == 156 && rdesc[41] == 1) { + hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n"); + rdesc[41] = 0; + } return rdesc; }
@@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev) model = "Model O"; break; case USB_DEVICE_ID_GLORIOUS_MODEL_D: model = "Model D"; break; + case USB_DEVICE_ID_GLORIOUS_MODEL_I: + model = "Model I"; break; }
snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model); @@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev, }
static const struct hid_device_id glorious_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, + { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, USB_DEVICE_ID_GLORIOUS_MODEL_O) }, - { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, + { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, USB_DEVICE_ID_GLORIOUS_MODEL_D) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW, + USB_DEVICE_ID_GLORIOUS_MODEL_I) }, { } }; MODULE_DEVICE_TABLE(hid, glorious_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7c688d7f8ccff..6273ab615af89 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -471,10 +471,6 @@ #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
-#define USB_VENDOR_ID_GLORIOUS 0x258a -#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 -#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 - #define I2C_VENDOR_ID_GOODIX 0x27c6 #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0
@@ -697,6 +693,9 @@ #define USB_VENDOR_ID_LABTEC 0x1020 #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
+#define USB_VENDOR_ID_LAVIEW 0x22D4 +#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503 + #define USB_VENDOR_ID_LCPOWER 0x1241 #define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
@@ -1068,6 +1067,10 @@ #define USB_VENDOR_ID_SIGMATEL 0x066F #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
+#define USB_VENDOR_ID_SINOWEALTH 0x258a +#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 +#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 + #define USB_VENDOR_ID_SIS_TOUCH 0x0457 #define USB_DEVICE_ID_SIS9200_TOUCH 0x9200 #define USB_DEVICE_ID_SIS817_TOUCH 0x0817
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
[ Upstream commit c55092187d9ad7b2f8f5a8645286fa03997d442f ]
These devices disconnect if suspended without remote wakeup. They can operate with the standard driver.
Signed-off-by: Oliver Neukum oneukum@suse.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-quirks.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 787349f2de01d..1b3a83fa76168 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET },
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis Benato benato.denis96@gmail.com
[ Upstream commit 546edbd26cff7ae990e480a59150e801a06f77b1 ]
Some devices managed by this driver automatically set brightness to 0 before entering a suspended state and reset it back to a default brightness level after the resume: this has the effect of having the kernel report wrong brightness status after a sleep, and on some devices (like the Asus RC71L) that brightness is the intensity of LEDs directly facing the user.
Fix the above issue by setting back brightness to the level it had before entering a sleep state.
Signed-off-by: Denis Benato benato.denis96@gmail.com Signed-off-by: Luke D. Jones luke@ljones.dev Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-asus.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 6865cab33cf8a..52b0ef99bc955 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -901,6 +901,24 @@ static int asus_start_multitouch(struct hid_device *hdev) return 0; }
+static int __maybe_unused asus_resume(struct hid_device *hdev) { + struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + int ret = 0; + + if (drvdata->kbd_backlight) { + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, + drvdata->kbd_backlight->cdev.brightness }; + ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); + if (ret < 0) { + hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); + goto asus_resume_err; + } + } + +asus_resume_err: + return ret; +} + static int __maybe_unused asus_reset_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); @@ -1177,6 +1195,7 @@ static struct hid_driver asus_driver = { .input_configured = asus_input_configured, #ifdef CONFIG_PM .reset_resume = asus_reset_resume, + .resume = asus_resume, #endif .event = asus_event, .raw_event = asus_raw_event
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aoba K nexp_0x17@outlook.com
[ Upstream commit 9ffccb691adb854e7b7f3ee57fbbda12ff70533f ]
Honor MagicBook 13 2023 has a touchpad which do not switch to the multitouch mode until the input mode feature is written by the host. The touchpad do report the input mode at touchpad(3), while itself working under mouse mode. As a workaround, it is possible to call MT_QUIRE_FORCE_GET_FEATURE to force set feature in mt_set_input_mode for such device.
The touchpad reports as BLTP7853, which cannot retrive any useful manufacture information on the internel by this string at present. As the serial number of the laptop is GLO-G52, while DMI info reports the laptop serial number as GLO-GXXX, this workaround should applied to all models which has the GLO-GXXX.
Signed-off-by: Aoba K nexp_0x17@outlook.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-multitouch.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 84b12599eaf69..7d43d62df2409 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1962,6 +1962,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
+ /* HONOR GLO-GXXX panel */ + { .driver_data = MT_CLS_VTL, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + 0x347d, 0x7853) }, + /* Ilitek dual touch panel */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit 125b0bb95dd6bec81b806b997a4ccb026eeecf8f ]
We really don't want to do atomic_read() or anything like that, since we already have the value, not the lock. The whole point of this is that we've loaded the lock from memory, and we want to check whether the value we loaded was a locked one or not.
The main use of this is the lockref code, which loads both the lock and the reference count in one atomic operation, and then works on that combined value. With the atomic_read(), the compiler would pointlessly spill the value to the stack, in order to then be able to read it back "atomically".
This is the qspinlock version of commit c6f4a9002252 ("asm-generic: ticket-lock: Optimize arch_spin_value_unlocked()") which fixed this same bug for ticket locks.
Cc: Guo Ren guoren@kernel.org Cc: Ingo Molnar mingo@kernel.org Cc: Waiman Long longman@redhat.com Link: https://lore.kernel.org/all/CAHk-=whNRv0v6kQiV5QO6DJhjH4KEL36vWQ6Re8Csrnh4zb... Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/asm-generic/qspinlock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h index 4fe7fd0fe834d..d1ddbcf71791d 100644 --- a/include/asm-generic/qspinlock.h +++ b/include/asm-generic/qspinlock.h @@ -41,7 +41,7 @@ static __always_inline int queued_spin_is_locked(struct qspinlock *lock) */ static __always_inline int queued_spin_value_unlocked(struct qspinlock lock) { - return !atomic_read(&lock.val); + return !lock.val.counter; }
/**
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lech Perczak lech.perczak@gmail.com
[ Upstream commit 99360d9620f09fb8bc15548d855011bbb198c680 ]
Interface 4 is used by for QMI interface in stock firmware of MF28D, the router which uses MF290 modem. Rebind it to qmi_wwan after freeing it up from option driver. The proper configuration is:
Interface mapping is: 0: QCDM, 1: (unknown), 2: AT (PCUI), 2: AT (Modem), 4: QMI
T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=19d2 ProdID=0189 Rev= 0.00 S: Manufacturer=ZTE, Incorporated S: Product=ZTE LTE Technologies MSM C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
Cc: Bjørn Mork bjorn@mork.no Signed-off-by: Lech Perczak lech.perczak@gmail.com Link: https://lore.kernel.org/r/20231117231918.100278-3-lech.perczak@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 5cf7f389bf4ef..3d342908f57a0 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1225,6 +1225,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, + {QMI_FIXED_INTF(0x19d2, 0x0189, 4)}, /* ZTE MF290 */ {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ {QMI_FIXED_INTF(0x19d2, 0x0200, 1)},
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis Benato benato.denis96@gmail.com
[ Upstream commit 06ae5afce8cc1f7621cc5c7751e449ce20d68af7 ]
In the function asus_kbd_set_report the parameter buf is read-only as it gets copied in a memory portion suitable for USB transfer, but the parameter is not marked as const: add the missing const and mark const immutable buffers passed to that function.
Signed-off-by: Denis Benato benato.denis96@gmail.com Signed-off-by: Luke D. Jones luke@ljones.dev Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-asus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 52b0ef99bc955..b46fb92d28e58 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -336,7 +336,7 @@ static int asus_raw_event(struct hid_device *hdev, return 0; }
-static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) +static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) { unsigned char *dmabuf; int ret; @@ -355,7 +355,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size
static int asus_kbd_init(struct hid_device *hdev) { - u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; int ret;
@@ -369,7 +369,7 @@ static int asus_kbd_init(struct hid_device *hdev) static int asus_kbd_get_functions(struct hid_device *hdev, unsigned char *kbd_func) { - u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; u8 *readbuf; int ret;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland mark.rutland@arm.com
commit 7e2c1e4b34f07d9aa8937fab88359d4a0fce468e upstream.
When lockdep is enabled, the for_each_sibling_event(sibling, event) macro checks that event->ctx->mutex is held. When creating a new group leader event, we call perf_event_validate_size() on a partially initialized event where event->ctx is NULL, and so when for_each_sibling_event() attempts to check event->ctx->mutex, we get a splat, as reported by Lucas De Marchi:
WARNING: CPU: 8 PID: 1471 at kernel/events/core.c:1950 __do_sys_perf_event_open+0xf37/0x1080
This only happens for a new event which is its own group_leader, and in this case there cannot be any sibling events. Thus it's safe to skip the check for siblings, which avoids having to make invasive and ugly changes to for_each_sibling_event().
Avoid the splat by bailing out early when the new event is its own group_leader.
Fixes: 382c27f4ed28f803 ("perf: Fix perf_event_validate_size()") Closes: https://lore.kernel.org/lkml/20231214000620.3081018-1-lucas.demarchi@intel.c... Closes: https://lore.kernel.org/lkml/ZXpm6gQ%2Fd59jGsuW@xpf.sh.intel.com/ Reported-by: Lucas De Marchi lucas.demarchi@intel.com Reported-by: Pengfei Xu pengfei.xu@intel.com Signed-off-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20231215112450.3972309-1-mark.rutland@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/events/core.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2039,6 +2039,16 @@ static bool perf_event_validate_size(str group_leader->nr_siblings + 1) > 16*1024) return false;
+ /* + * When creating a new group leader, group_leader->ctx is initialized + * after the size has been validated, but we cannot safely use + * for_each_sibling_event() until group_leader->ctx is set. A new group + * leader cannot have any siblings yet, so we can safely skip checking + * the non-existent siblings. + */ + if (event == group_leader) + return true; + for_each_sibling_event(sibling, group_leader) { if (__perf_event_read_size(sibling->attr.read_format, group_leader->nr_siblings + 1) > 16*1024)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
commit e199bf52ffda8f98f129728d57244a9cd9ad5623 upstream.
If bus is marked as multi_link, but number of masters in the stream is not higher than bus->hw_sync_min_links (bus->multi_link && m_rt_count >= bus->hw_sync_min_links), bank switching should not happen. The first part of do_bank_switch() code properly takes these conditions into account, but second part (sdw_ml_sync_bank_switch()) relies purely on bus->multi_link property. This is not balanced and leads to NULL pointer dereference:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 ... Call trace: wait_for_completion_timeout+0x124/0x1f0 do_bank_switch+0x370/0x6f8 sdw_prepare_stream+0x2d0/0x438 qcom_snd_sdw_prepare+0xa0/0x118 sm8450_snd_prepare+0x128/0x148 snd_soc_link_prepare+0x5c/0xe8 __soc_pcm_prepare+0x28/0x1ec dpcm_be_dai_prepare+0x1e0/0x2c0 dpcm_fe_dai_prepare+0x108/0x28c snd_pcm_do_prepare+0x44/0x68 snd_pcm_action_single+0x54/0xc0 snd_pcm_action_nonatomic+0xe4/0xec snd_pcm_prepare+0xc4/0x114 snd_pcm_common_ioctl+0x1154/0x1cc0 snd_pcm_ioctl+0x54/0x74
Fixes: ce6e74d008ff ("soundwire: Add support for multi link bank switch") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20231124180136.390621-1-krzysztof.kozlowski@linaro... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soundwire/stream.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -724,14 +724,15 @@ error_1: * sdw_ml_sync_bank_switch: Multilink register bank switch * * @bus: SDW bus instance + * @multi_link: whether this is a multi-link stream with hardware-based sync * * Caller function should free the buffers on error */ -static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) +static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link) { unsigned long time_left;
- if (!bus->multi_link) + if (!multi_link) return 0;
/* Wait for completion of transfer */ @@ -827,7 +828,7 @@ static int do_bank_switch(struct sdw_str bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT;
/* Check if bank switch was successful */ - ret = sdw_ml_sync_bank_switch(bus); + ret = sdw_ml_sync_bank_switch(bus, multi_link); if (ret < 0) { dev_err(bus->dev, "multi link bank switch failed: %d\n", ret);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li libaokun1@huawei.com
commit 2dcf5fde6dffb312a4bfb8ef940cea2d1f402e32 upstream.
For files with logical blocks close to EXT_MAX_BLOCKS, the file size predicted in ext4_mb_normalize_request() may exceed EXT_MAX_BLOCKS. This can cause some blocks to be preallocated that will not be used. And after [Fixes], the following issue may be triggered:
========================================================= kernel BUG at fs/ext4/mballoc.c:4653! Internal error: Oops - BUG: 00000000f2000800 [#1] SMP CPU: 1 PID: 2357 Comm: xfs_io 6.7.0-rc2-00195-g0f5cc96c367f Hardware name: linux,dummy-virt (DT) pc : ext4_mb_use_inode_pa+0x148/0x208 lr : ext4_mb_use_inode_pa+0x98/0x208 Call trace: ext4_mb_use_inode_pa+0x148/0x208 ext4_mb_new_inode_pa+0x240/0x4a8 ext4_mb_use_best_found+0x1d4/0x208 ext4_mb_try_best_found+0xc8/0x110 ext4_mb_regular_allocator+0x11c/0xf48 ext4_mb_new_blocks+0x790/0xaa8 ext4_ext_map_blocks+0x7cc/0xd20 ext4_map_blocks+0x170/0x600 ext4_iomap_begin+0x1c0/0x348 =========================================================
Here is a calculation when adjusting ac_b_ex in ext4_mb_new_inode_pa():
ex.fe_logical = orig_goal_end - EXT4_C2B(sbi, ex.fe_len); if (ac->ac_o_ex.fe_logical >= ex.fe_logical) goto adjust_bex;
The problem is that when orig_goal_end is subtracted from ac_b_ex.fe_len it is still greater than EXT_MAX_BLOCKS, which causes ex.fe_logical to overflow to a very small value, which ultimately triggers a BUG_ON in ext4_mb_new_inode_pa() because pa->pa_free < len.
The last logical block of an actual write request does not exceed EXT_MAX_BLOCKS, so in ext4_mb_normalize_request() also avoids normalizing the last logical block to exceed EXT_MAX_BLOCKS to avoid the above issue.
The test case in [Link] can reproduce the above issue with 64k block size.
Link: https://patchwork.kernel.org/project/fstests/list/?series=804003 Cc: stable@kernel.org # 6.4 Fixes: 93cdf49f6eca ("ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa()") Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20231127063313.3734294-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3603,6 +3603,10 @@ ext4_mb_normalize_request(struct ext4_al start = max(start, rounddown(ac->ac_o_ex.fe_logical, (ext4_lblk_t)EXT4_BLOCKS_PER_GROUP(ac->ac_sb)));
+ /* avoid unnecessary preallocation that may trigger assertions */ + if (start + size > EXT_MAX_BLOCKS) + size = EXT_MAX_BLOCKS - start; + /* don't cover already allocated blocks in selected range */ if (ar->pleft && start <= ar->lleft) { size -= ar->lleft + 1 - start;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Houghton jthoughton@google.com
commit 3c0696076aad60a2f04c019761921954579e1b0e upstream.
It is currently possible for a userspace application to enter an infinite page fault loop when using HugeTLB pages implemented with contiguous PTEs when HAFDBS is not available. This happens because:
1. The kernel may sometimes write PTEs that are sw-dirty but hw-clean (PTE_DIRTY | PTE_RDONLY | PTE_WRITE).
2. If, during a write, the CPU uses a sw-dirty, hw-clean PTE in handling the memory access on a system without HAFDBS, we will get a page fault.
3. HugeTLB will check if it needs to update the dirty bits on the PTE. For contiguous PTEs, it will check to see if the pgprot bits need updating. In this case, HugeTLB wants to write a sequence of sw-dirty, hw-dirty PTEs, but it finds that all the PTEs it is about to overwrite are all pte_dirty() (pte_sw_dirty() => pte_dirty()), so it thinks no update is necessary.
We can get the kernel to write a sw-dirty, hw-clean PTE with the following steps (showing the relevant VMA flags and pgprot bits):
i. Create a valid, writable contiguous PTE. VMA vmflags: VM_SHARED | VM_READ | VM_WRITE VMA pgprot bits: PTE_RDONLY | PTE_WRITE PTE pgprot bits: PTE_DIRTY | PTE_WRITE
ii. mprotect the VMA to PROT_NONE. VMA vmflags: VM_SHARED VMA pgprot bits: PTE_RDONLY PTE pgprot bits: PTE_DIRTY | PTE_RDONLY
iii. mprotect the VMA back to PROT_READ | PROT_WRITE. VMA vmflags: VM_SHARED | VM_READ | VM_WRITE VMA pgprot bits: PTE_RDONLY | PTE_WRITE PTE pgprot bits: PTE_DIRTY | PTE_WRITE | PTE_RDONLY
Make it impossible to create a writeable sw-dirty, hw-clean PTE with pte_modify(). Such a PTE should be impossible to create, and there may be places that assume that pte_dirty() implies pte_hw_dirty().
Signed-off-by: James Houghton jthoughton@google.com Fixes: 031e6e6b4e12 ("arm64: hugetlb: Avoid unnecessary clearing in huge_ptep_set_access_flags") Cc: stable@vger.kernel.org Acked-by: Will Deacon will@kernel.org Reviewed-by: Ryan Roberts ryan.roberts@arm.com Link: https://lore.kernel.org/r/20231204172646.2541916-3-jthoughton@google.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/pgtable.h | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -744,6 +744,12 @@ static inline pte_t pte_modify(pte_t pte if (pte_hw_dirty(pte)) pte = pte_mkdirty(pte); pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); + /* + * If we end up clearing hw dirtiness for a sw-dirty PTE, set hardware + * dirtiness again. + */ + if (pte_sw_dirty(pte)) + pte = pte_mkdirty(pte); return pte; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florent Revest revest@chromium.org
commit c12296bbecc488623b7d1932080e394d08f3226b upstream.
In __team_options_register, team_options are allocated and appended to the team's option_list. If one option instance allocation fails, the "inst_rollback" cleanup path frees the previously allocated options but doesn't remove them from the team's option_list. This leaves dangling pointers that can be dereferenced later by other parts of the team driver that iterate over options.
This patch fixes the cleanup path to remove the dangling pointers from the list.
As far as I can tell, this uaf doesn't have much security implications since it would be fairly hard to exploit (an attacker would need to make the allocation of that specific small object fail) but it's still nice to fix.
Cc: stable@vger.kernel.org Fixes: 80f7c6683fe0 ("team: add support for per-port options") Signed-off-by: Florent Revest revest@chromium.org Reviewed-by: Jiri Pirko jiri@nvidia.com Reviewed-by: Hangbin Liu liuhangbin@gmail.com Link: https://lore.kernel.org/r/20231206123719.1963153-1-revest@chromium.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/team/team.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -284,8 +284,10 @@ static int __team_options_register(struc return 0;
inst_rollback: - for (i--; i >= 0; i--) + for (i--; i >= 0; i--) { __team_option_inst_del_option(team, dst_opts[i]); + list_del(&dst_opts[i]->list); + }
i = option_count; alloc_rollback:
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit 17d801758157bec93f26faaf5ff1a8b9a552d67a upstream.
Reading the ring buffer does a swap of a sub-buffer within the ring buffer with a empty sub-buffer. This allows the reader to have full access to the content of the sub-buffer that was swapped out without having to worry about contention with the writer.
The readers call ring_buffer_alloc_read_page() to allocate a page that will be used to swap with the ring buffer. When the code is finished with the reader page, it calls ring_buffer_free_read_page(). Instead of freeing the page, it stores it as a spare. Then next call to ring_buffer_alloc_read_page() will return this spare instead of calling into the memory management system to allocate a new page.
Unfortunately, on freeing of the ring buffer, this spare page is not freed, and causes a memory leak.
Link: https://lore.kernel.org/linux-trace-kernel/20231210221250.7b9cc83c@rorschach...
Cc: stable@vger.kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Fixes: 73a757e63114d ("ring-buffer: Return reader page back into existing ring buffer") Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1667,6 +1667,8 @@ static void rb_free_cpu_buffer(struct ri free_buffer_page(bpage); }
+ free_page((unsigned long)cpu_buffer->free_page); + kfree(cpu_buffer); }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit d06aff1cb13d2a0d52b48e605462518149c98c81 upstream.
The snapshot buffer is to mimic the main buffer so that when a snapshot is needed, the snapshot and main buffer are swapped. When the snapshot buffer is allocated, it is set to the minimal size that the ring buffer may be at and still functional. When it is allocated it becomes the same size as the main ring buffer, and when the main ring buffer changes in size, it should do.
Currently, the resize only updates the snapshot buffer if it's used by the current tracer (ie. the preemptirqsoff tracer). But it needs to be updated anytime it is allocated.
When changing the size of the main buffer, instead of looking to see if the current tracer is utilizing the snapshot buffer, just check if it is allocated to know if it should be updated or not.
Also fix typo in comment just above the code change.
Link: https://lore.kernel.org/linux-trace-kernel/20231210225447.48476a6a@rorschach...
Cc: stable@vger.kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Fixes: ad909e21bbe69 ("tracing: Add internal tracing_snapshot() functions") Reviewed-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5905,7 +5905,7 @@ static int __tracing_resize_ring_buffer( if (!tr->array_buffer.buffer) return 0;
- /* Do not allow tracing while resizng ring buffer */ + /* Do not allow tracing while resizing ring buffer */ tracing_stop_tr(tr);
ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu); @@ -5913,7 +5913,7 @@ static int __tracing_resize_ring_buffer( goto out_start;
#ifdef CONFIG_TRACER_MAX_TRACE - if (!tr->current_trace->use_max_tr) + if (!tr->allocated_snapshot) goto out;
ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu);
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit b049525855fdd0024881c9b14b8fbec61c3f53d3 upstream.
For the ring buffer iterator (non-consuming read), the event needs to be copied into the iterator buffer to make sure that a writer does not overwrite it while the user is reading it. If a write happens during the copy, the buffer is simply discarded.
But the temp buffer itself was not big enough. The allocation of the buffer was only BUF_MAX_DATA_SIZE, which is the maximum data size that can be passed into the ring buffer and saved. But the temp buffer needs to hold the meta data as well. That would be BUF_PAGE_SIZE and not BUF_MAX_DATA_SIZE.
Link: https://lore.kernel.org/linux-trace-kernel/20231212072558.61f76493@gandalf.l...
Cc: stable@vger.kernel.org Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Fixes: 785888c544e04 ("ring-buffer: Have rb_iter_head_event() handle concurrent writer") Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2275,7 +2275,7 @@ rb_iter_head_event(struct ring_buffer_it */ barrier();
- if ((iter->head + length) > commit || length > BUF_MAX_DATA_SIZE) + if ((iter->head + length) > commit || length > BUF_PAGE_SIZE) /* Writer corrupted the read? */ goto reset;
@@ -4836,7 +4836,8 @@ ring_buffer_read_prepare(struct trace_bu if (!iter) return NULL;
- iter->event = kmalloc(BUF_MAX_DATA_SIZE, flags); + /* Holds the entire event: data and meta data */ + iter->event = kmalloc(BUF_PAGE_SIZE, flags); if (!iter->event) { kfree(iter); return NULL;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit b3ae7b67b87fed771fa5bf95389df06b0433603e upstream.
The maximum ring buffer data size is the maximum size of data that can be recorded on the ring buffer. Events must be smaller than the sub buffer data size minus any meta data. This size is checked before trying to allocate from the ring buffer because the allocation assumes that the size will fit on the sub buffer.
The maximum size was calculated as the size of a sub buffer page (which is currently PAGE_SIZE minus the sub buffer header) minus the size of the meta data of an individual event. But it missed the possible adding of a time stamp for events that are added long enough apart that the event meta data can't hold the time delta.
When an event is added that is greater than the current BUF_MAX_DATA_SIZE minus the size of a time stamp, but still less than or equal to BUF_MAX_DATA_SIZE, the ring buffer would go into an infinite loop, looking for a page that can hold the event. Luckily, there's a check for this loop and after 1000 iterations and a warning is emitted and the ring buffer is disabled. But this should never happen.
This can happen when a large event is added first, or after a long period where an absolute timestamp is prefixed to the event, increasing its size by 8 bytes. This passes the check and then goes into the algorithm that causes the infinite loop.
For events that are the first event on the sub-buffer, it does not need to add a timestamp, because the sub-buffer itself contains an absolute timestamp, and adding one is redundant.
The fix is to check if the event is to be the first event on the sub-buffer, and if it is, then do not add a timestamp.
This also fixes 32 bit adding a timestamp when a read of before_stamp or write_stamp is interrupted. There's still no need to add that timestamp if the event is going to be the first event on the sub buffer.
Also, if the buffer has "time_stamp_abs" set, then also check if the length plus the timestamp is greater than the BUF_MAX_DATA_SIZE.
Link: https://lore.kernel.org/all/20231212104549.58863438@gandalf.local.home/ Link: https://lore.kernel.org/linux-trace-kernel/20231212071837.5fdd6c13@gandalf.l... Link: https://lore.kernel.org/linux-trace-kernel/20231212111617.39e02849@gandalf.l...
Cc: stable@vger.kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Fixes: a4543a2fa9ef3 ("ring-buffer: Get timestamp after event is allocated") Fixes: 58fbc3c63275c ("ring-buffer: Consolidate add_timestamp to remove some branches") Reported-by: Kent Overstreet kent.overstreet@linux.dev # (on IRC) Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -3301,7 +3301,10 @@ __rb_reserve_next(struct ring_buffer_per * absolute timestamp. * Don't bother if this is the start of a new page (w == 0). */ - if (unlikely(!a_ok || !b_ok || (info->before != info->after && w))) { + if (!w) { + /* Use the sub-buffer timestamp */ + info->delta = 0; + } else if (unlikely(!a_ok || !b_ok || info->before != info->after)) { info->add_timestamp |= RB_ADD_STAMP_FORCE | RB_ADD_STAMP_EXTEND; info->length += RB_LEN_TIME_EXTEND; } else { @@ -3456,6 +3459,8 @@ rb_reserve_next_event(struct trace_buffe if (ring_buffer_time_stamp_abs(cpu_buffer->buffer)) { add_ts_default = RB_ADD_STAMP_ABSOLUTE; info.length += RB_LEN_TIME_EXTEND; + if (info.length > BUF_MAX_DATA_SIZE) + goto out_fail; } else { add_ts_default = RB_ADD_STAMP_NONE; }
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt (Google) rostedt@goodmis.org
commit fff88fa0fbc7067ba46dde570912d63da42c59a9 upstream.
Mathieu Desnoyers pointed out an issue in the rb_time_cmpxchg() for 32 bit architectures. That is:
static bool rb_time_cmpxchg(rb_time_t *t, u64 expect, u64 set) { unsigned long cnt, top, bottom, msb; unsigned long cnt2, top2, bottom2, msb2; u64 val;
/* The cmpxchg always fails if it interrupted an update */ if (!__rb_time_read(t, &val, &cnt2)) return false;
if (val != expect) return false;
<<<< interrupted here!
cnt = local_read(&t->cnt);
The problem is that the synchronization counter in the rb_time_t is read *after* the value of the timestamp is read. That means if an interrupt were to come in between the value being read and the counter being read, it can change the value and the counter and the interrupted process would be clueless about it!
The counter needs to be read first and then the value. That way it is easy to tell if the value is stale or not. If the counter hasn't been updated, then the value is still good.
Link: https://lore.kernel.org/linux-trace-kernel/20231211201324.652870-1-mathieu.d... Link: https://lore.kernel.org/linux-trace-kernel/20231212115301.7a9c9a64@gandalf.l...
Cc: stable@vger.kernel.org Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Mark Rutland mark.rutland@arm.com Fixes: 10464b4aa605e ("ring-buffer: Add rb_time_t 64 bit operations for speeding up 32 bit") Reported-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Reviewed-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -703,6 +703,9 @@ static int rb_time_cmpxchg(rb_time_t *t, unsigned long cnt2, top2, bottom2; u64 val;
+ /* Any interruptions in this function should cause a failure */ + cnt = local_read(&t->cnt); + /* The cmpxchg always fails if it interrupted an update */ if (!__rb_time_read(t, &val, &cnt2)) return false; @@ -710,7 +713,6 @@ static int rb_time_cmpxchg(rb_time_t *t, if (val != expect) return false;
- cnt = local_read(&t->cnt); if ((cnt & 3) != cnt2) return false;
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roy Luo royluo@google.com
commit 73ea73affe8622bdf292de898da869d441da6a9d upstream.
The KOBJ_CHANGE uevent is sent before gadget unbind is actually executed, resulting in inaccurate uevent emitted at incorrect timing (the uevent would have USB_UDC_DRIVER variable set while it would soon be removed). Move the KOBJ_CHANGE uevent to the end of the unbind function so that uevent is sent only after the change has been made.
Fixes: 2ccea03a8f7e ("usb: gadget: introduce UDC Class") Cc: stable@vger.kernel.org Signed-off-by: Roy Luo royluo@google.com Link: https://lore.kernel.org/r/20231128221756.2591158-1-royluo@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/gadget/udc/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1353,8 +1353,6 @@ static void usb_gadget_remove_driver(str dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n", udc->driver->function);
- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); - usb_gadget_disconnect(udc->gadget); if (udc->gadget->irq) synchronize_irq(udc->gadget->irq); @@ -1363,6 +1361,8 @@ static void usb_gadget_remove_driver(str
udc->driver = NULL; udc->gadget->dev.driver = NULL; + + kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); }
/**
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Starke daniel.starke@siemens.com
commit 01aecd917114577c423f07cec0d186ad007d76fc upstream.
The current implementation registers/deregisters the user ttys at mux attach/detach. That means that the user devices are available before any control channel is open. However, user channel initialization requires an open control channel. Furthermore, the user is not informed if the mux restarts due to configuration changes. Put the registration/deregistration procedure into separate function to improve readability. Move registration to mux activation and deregistration to mux cleanup to keep the user devices only open as long as a control channel exists. The user will be informed via the device driver if the mux was reconfigured in a way that required a mux re-activation. This makes it necessary to add T2 initialization to gsmld_open() for the ldisc open code path (not the reconfiguration code path) to avoid deletion of an uninitialized T2 at mux cleanup.
Fixes: d50f6dcaf22a ("tty: n_gsm: expose gsmtty device nodes at ldisc open time") Signed-off-by: Daniel Starke daniel.starke@siemens.com Link: https://lore.kernel.org/r/20220701061652.39604-2-daniel.starke@siemens.com Signed-off-by: Gavrilov Ilia Ilia.Gavrilov@infotecs.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/n_gsm.c | 117 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 38 deletions(-)
--- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -235,6 +235,7 @@ struct gsm_mux { struct gsm_dlci *dlci[NUM_DLCI]; int old_c_iflag; /* termios c_iflag value before attach */ bool constipated; /* Asked by remote to shut up */ + bool has_devices; /* Devices were registered */
spinlock_t tx_lock; unsigned int tx_bytes; /* TX data outstanding */ @@ -465,6 +466,68 @@ static u8 gsm_encode_modem(const struct }
/** + * gsm_register_devices - register all tty devices for a given mux index + * + * @driver: the tty driver that describes the tty devices + * @index: the mux number is used to calculate the minor numbers of the + * ttys for this mux and may differ from the position in the + * mux array. + */ +static int gsm_register_devices(struct tty_driver *driver, unsigned int index) +{ + struct device *dev; + int i; + unsigned int base; + + if (!driver || index >= MAX_MUX) + return -EINVAL; + + base = index * NUM_DLCI; /* first minor for this index */ + for (i = 1; i < NUM_DLCI; i++) { + /* Don't register device 0 - this is the control channel + * and not a usable tty interface + */ + dev = tty_register_device(gsm_tty_driver, base + i, NULL); + if (IS_ERR(dev)) { + if (debug & 8) + pr_info("%s failed to register device minor %u", + __func__, base + i); + for (i--; i >= 1; i--) + tty_unregister_device(gsm_tty_driver, base + i); + return PTR_ERR(dev); + } + } + + return 0; +} + +/** + * gsm_unregister_devices - unregister all tty devices for a given mux index + * + * @driver: the tty driver that describes the tty devices + * @index: the mux number is used to calculate the minor numbers of the + * ttys for this mux and may differ from the position in the + * mux array. + */ +static void gsm_unregister_devices(struct tty_driver *driver, + unsigned int index) +{ + int i; + unsigned int base; + + if (!driver || index >= MAX_MUX) + return; + + base = index * NUM_DLCI; /* first minor for this index */ + for (i = 1; i < NUM_DLCI; i++) { + /* Don't unregister device 0 - this is the control + * channel and not a usable tty interface + */ + tty_unregister_device(gsm_tty_driver, base + i); + } +} + +/** * gsm_print_packet - display a frame for debug * @hdr: header to print before decode * @addr: address EA from the frame @@ -2178,6 +2241,10 @@ static void gsm_cleanup_mux(struct gsm_m del_timer_sync(&gsm->t2_timer);
/* Free up any link layer users and finally the control channel */ + if (gsm->has_devices) { + gsm_unregister_devices(gsm_tty_driver, gsm->num); + gsm->has_devices = false; + } for (i = NUM_DLCI - 1; i >= 0; i--) if (gsm->dlci[i]) gsm_dlci_release(gsm->dlci[i]); @@ -2201,15 +2268,21 @@ static void gsm_cleanup_mux(struct gsm_m static int gsm_activate_mux(struct gsm_mux *gsm) { struct gsm_dlci *dlci; + int ret;
if (gsm->encoding == 0) gsm->receive = gsm0_receive; else gsm->receive = gsm1_receive;
+ ret = gsm_register_devices(gsm_tty_driver, gsm->num); + if (ret) + return ret; + dlci = gsm_dlci_alloc(gsm, 0); if (dlci == NULL) return -ENOMEM; + gsm->has_devices = true; gsm->dead = false; /* Tty opens are now permissible */ return 0; } @@ -2475,39 +2548,14 @@ static int gsmld_output(struct gsm_mux * * will need moving to an ioctl path. */
-static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) +static void gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) { - unsigned int base; - int ret, i; - gsm->tty = tty_kref_get(tty); /* Turn off tty XON/XOFF handling to handle it explicitly. */ gsm->old_c_iflag = tty->termios.c_iflag; tty->termios.c_iflag &= (IXON | IXOFF); - ret = gsm_activate_mux(gsm); - if (ret != 0) - tty_kref_put(gsm->tty); - else { - /* Don't register device 0 - this is the control channel and not - a usable tty interface */ - base = mux_num_to_base(gsm); /* Base for this MUX */ - for (i = 1; i < NUM_DLCI; i++) { - struct device *dev; - - dev = tty_register_device(gsm_tty_driver, - base + i, NULL); - if (IS_ERR(dev)) { - for (i--; i >= 1; i--) - tty_unregister_device(gsm_tty_driver, - base + i); - return PTR_ERR(dev); - } - } - } - return ret; }
- /** * gsmld_detach_gsm - stop doing 0710 mux * @tty: tty attached to the mux @@ -2518,12 +2566,7 @@ static int gsmld_attach_gsm(struct tty_s
static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) { - unsigned int base = mux_num_to_base(gsm); /* Base for this MUX */ - int i; - WARN_ON(tty != gsm->tty); - for (i = 1; i < NUM_DLCI; i++) - tty_unregister_device(gsm_tty_driver, base + i); /* Restore tty XON/XOFF handling. */ gsm->tty->termios.c_iflag = gsm->old_c_iflag; tty_kref_put(gsm->tty); @@ -2619,7 +2662,6 @@ static void gsmld_close(struct tty_struc static int gsmld_open(struct tty_struct *tty) { struct gsm_mux *gsm; - int ret;
if (tty->ops->write == NULL) return -EINVAL; @@ -2635,12 +2677,11 @@ static int gsmld_open(struct tty_struct /* Attach the initial passive connection */ gsm->encoding = 1;
- ret = gsmld_attach_gsm(tty, gsm); - if (ret != 0) { - gsm_cleanup_mux(gsm, false); - mux_put(gsm); - } - return ret; + gsmld_attach_gsm(tty, gsm); + + timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); + + return 0; }
/**
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby jslaby@suse.cz
commit b93db97e1ca08e500305bc46b08c72e2232c4be1 upstream.
dp, f, and i are only duplicates of gsmld_receive_buf's parameters. Use the parameters directly (cp, fp, and count) and delete these local variables.
Signed-off-by: Jiri Slaby jslaby@suse.cz Link: https://lore.kernel.org/r/20210302062214.29627-41-jslaby@suse.cz Signed-off-by: Gavrilov Ilia Ilia.Gavrilov@infotecs.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/n_gsm.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
--- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2577,27 +2577,24 @@ static void gsmld_receive_buf(struct tty char *fp, int count) { struct gsm_mux *gsm = tty->disc_data; - const unsigned char *dp; - char *f; - int i; char flags = TTY_NORMAL;
if (debug & 4) print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET, cp, count);
- for (i = count, dp = cp, f = fp; i; i--, dp++) { - if (f) - flags = *f++; + for (; count; count--, cp++) { + if (fp) + flags = *fp++; switch (flags) { case TTY_NORMAL: - gsm->receive(gsm, *dp); + gsm->receive(gsm, *cp); break; case TTY_OVERRUN: case TTY_BREAK: case TTY_PARITY: case TTY_FRAME: - gsm_error(gsm, *dp, flags); + gsm_error(gsm, *cp, flags); break; default: WARN_ONCE(1, "%s: unknown flag %d\n",
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mazin Al Haddad mazinalhaddad05@gmail.com
commit f16c6d2e58a4c2b972efcf9eb12390ee0ba3befb upstream
A null pointer dereference can happen when attempting to access the "gsm->receive()" function in gsmld_receive_buf(). Currently, the code assumes that gsm->receive is only called after MUX activation. Since the gsmld_receive_buf() function can be accessed without the need to initialize the MUX, the gsm->receive() function will not be set and a NULL pointer dereference will occur.
Fix this by avoiding the call to "gsm->receive()" in case the function is not initialized by adding a sanity check.
Call Trace: <TASK> gsmld_receive_buf+0x1c2/0x2f0 drivers/tty/n_gsm.c:2861 tiocsti drivers/tty/tty_io.c:2293 [inline] tty_ioctl+0xa75/0x15d0 drivers/tty/tty_io.c:2692 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Link: https://syzkaller.appspot.com/bug?id=bdf035c61447f8c6e0e6920315d577cb5cc35ac... Fixes: 01aecd917114 ("tty: n_gsm: fix tty registration before control channel open") Reported-and-tested-by: syzbot+e3563f0c94e188366dbb@syzkaller.appspotmail.com Signed-off-by: Mazin Al Haddad mazinalhaddad05@gmail.com Link: https://lore.kernel.org/r/20220814015211.84180-1-mazinalhaddad05@gmail.com Signed-off-by: Gavrilov Ilia Ilia.Gavrilov@infotecs.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/n_gsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2588,7 +2588,8 @@ static void gsmld_receive_buf(struct tty flags = *fp++; switch (flags) { case TTY_NORMAL: - gsm->receive(gsm, *cp); + if (gsm->receive) + gsm->receive(gsm, *cp); break; case TTY_OVERRUN: case TTY_BREAK:
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N Rao naveen@kernel.org
commit 41a506ef71eb38d94fe133f565c87c3e06ccc072 upstream.
With ppc64 -mprofile-kernel and ppc32 -pg, profiling instructions to call into ftrace are emitted right at function entry. The instruction sequence used is minimal to reduce overhead. Crucially, a stackframe is not created for the function being traced. This breaks stack unwinding since the function being traced does not have a stackframe for itself. As such, it never shows up in the backtrace:
/sys/kernel/debug/tracing # echo 1 > /proc/sys/kernel/stack_tracer_enabled /sys/kernel/debug/tracing # cat stack_trace Depth Size Location (17 entries) ----- ---- -------- 0) 4144 32 ftrace_call+0x4/0x44 1) 4112 432 get_page_from_freelist+0x26c/0x1ad0 2) 3680 496 __alloc_pages+0x290/0x1280 3) 3184 336 __folio_alloc+0x34/0x90 4) 2848 176 vma_alloc_folio+0xd8/0x540 5) 2672 272 __handle_mm_fault+0x700/0x1cc0 6) 2400 208 handle_mm_fault+0xf0/0x3f0 7) 2192 80 ___do_page_fault+0x3e4/0xbe0 8) 2112 160 do_page_fault+0x30/0xc0 9) 1952 256 data_access_common_virt+0x210/0x220 10) 1696 400 0xc00000000f16b100 11) 1296 384 load_elf_binary+0x804/0x1b80 12) 912 208 bprm_execve+0x2d8/0x7e0 13) 704 64 do_execveat_common+0x1d0/0x2f0 14) 640 160 sys_execve+0x54/0x70 15) 480 64 system_call_exception+0x138/0x350 16) 416 416 system_call_common+0x160/0x2c4
Fix this by having ftrace create a dummy stackframe for the function being traced. With this, backtraces now capture the function being traced:
/sys/kernel/debug/tracing # cat stack_trace Depth Size Location (17 entries) ----- ---- -------- 0) 3888 32 _raw_spin_trylock+0x8/0x70 1) 3856 576 get_page_from_freelist+0x26c/0x1ad0 2) 3280 64 __alloc_pages+0x290/0x1280 3) 3216 336 __folio_alloc+0x34/0x90 4) 2880 176 vma_alloc_folio+0xd8/0x540 5) 2704 416 __handle_mm_fault+0x700/0x1cc0 6) 2288 96 handle_mm_fault+0xf0/0x3f0 7) 2192 48 ___do_page_fault+0x3e4/0xbe0 8) 2144 192 do_page_fault+0x30/0xc0 9) 1952 608 data_access_common_virt+0x210/0x220 10) 1344 16 0xc0000000334bbb50 11) 1328 416 load_elf_binary+0x804/0x1b80 12) 912 64 bprm_execve+0x2d8/0x7e0 13) 848 176 do_execveat_common+0x1d0/0x2f0 14) 672 192 sys_execve+0x54/0x70 15) 480 64 system_call_exception+0x138/0x350 16) 416 416 system_call_common+0x160/0x2c4
This results in two additional stores in the ftrace entry code, but produces reliable backtraces.
Fixes: 153086644fd1 ("powerpc/ftrace: Add support for -mprofile-kernel ftrace ABI") Cc: stable@vger.kernel.org Signed-off-by: Naveen N Rao naveen@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230621051349.759567-1-naveen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/trace/ftrace_64_mprofile.S | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -36,6 +36,9 @@ _GLOBAL(ftrace_regs_caller) /* Save the original return address in A's stack frame */ std r0,LRSAVE(r1)
+ /* Create a minimal stack frame for representing B */ + stdu r1, -STACK_FRAME_MIN_SIZE(r1) + /* Create our stack frame + pt_regs */ stdu r1,-SWITCH_FRAME_SIZE(r1)
@@ -65,6 +68,8 @@ _GLOBAL(ftrace_regs_caller) mflr r7 /* Save it as pt_regs->nip */ std r7, _NIP(r1) + /* Also save it in B's stackframe header for proper unwind */ + std r7, LRSAVE+SWITCH_FRAME_SIZE(r1) /* Save the read LR in pt_regs->link */ std r0, _LINK(r1)
@@ -121,7 +126,7 @@ ftrace_regs_call: ld r2, 24(r1)
/* Pop our stack frame */ - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE
#ifdef CONFIG_LIVEPATCH /* Based on the cmpd above, if the NIP was altered handle livepatch */ @@ -153,6 +158,9 @@ _GLOBAL(ftrace_caller) /* Save the original return address in A's stack frame */ std r0, LRSAVE(r1)
+ /* Create a minimal stack frame for representing B */ + stdu r1, -STACK_FRAME_MIN_SIZE(r1) + /* Create our stack frame + pt_regs */ stdu r1, -SWITCH_FRAME_SIZE(r1)
@@ -166,6 +174,7 @@ _GLOBAL(ftrace_caller) /* Get the _mcount() call site out of LR */ mflr r7 std r7, _NIP(r1) + std r7, LRSAVE+SWITCH_FRAME_SIZE(r1)
/* Save callee's TOC in the ABI compliant location */ std r2, 24(r1) @@ -200,7 +209,7 @@ ftrace_call: ld r2, 24(r1)
/* Pop our stack frame */ - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE
/* Reload original LR */ ld r0, LRSAVE(r1)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N Rao naveen@kernel.org
commit 4b3338aaa74d7d4ec5b6734dc298f0db94ec83d2 upstream.
Commit 41a506ef71eb ("powerpc/ftrace: Create a dummy stackframe to fix stack unwind") added use of a new stack frame on ftrace entry to fix stack unwind. However, the commit missed updating the offset used while tearing down the ftrace stack when ftrace is disabled. Fix the same.
In addition, the commit missed saving the correct stack pointer in pt_regs. Update the same.
Fixes: 41a506ef71eb ("powerpc/ftrace: Create a dummy stackframe to fix stack unwind") Cc: stable@vger.kernel.org # v6.5+ Signed-off-by: Naveen N Rao naveen@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20231130065947.2188860-1-naveen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/trace/ftrace_64_mprofile.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -55,7 +55,7 @@ _GLOBAL(ftrace_regs_caller) SAVE_10GPRS(22, r1)
/* Save previous stack pointer (r1) */ - addi r8, r1, SWITCH_FRAME_SIZE + addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE std r8, GPR1(r1)
/* Load special regs for save below */ @@ -150,7 +150,7 @@ ftrace_no_trace: mflr r3 mtctr r3 REST_GPR(3, r1) - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE mtlr r0 bctr
On Mon, 18 Dec 2023 at 19:37, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.10.205 release. There are 62 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Dec 2023 13:50:31 +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.205-rc... 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
commit that is causing build failure, drm/atomic: Pass the full state to CRTC atomic begin and flush [ Upstream commit f6ebe9f9c9233a6114eb922aba9a0c9ccc2d2e14 ]
Build log: ------------ drivers/gpu/drm/sun4i/sun4i_crtc.c: In function 'sun4i_crtc_atomic_begin': drivers/gpu/drm/sun4i/sun4i_crtc.c:63:44: error: implicit declaration of function 'drm_atomic_get_old_crtc_state' [-Werror=implicit-function-declaration] 63 | struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/sun4i/sun4i_crtc.c:63:44: warning: initialization of 'struct drm_crtc_state *' from 'int' makes pointer from integer without a cast [-Wint-conversion] cc1: some warnings being treated as errors
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
Links: - https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10....
lore links, - https://lore.kernel.org/stable/CA+G9fYupBYRYc5eAdHt6TH+xfoCRE31=FpDMS+-QY3b6...
-- Linaro LKFT https://lkft.linaro.org
Naresh Kamboju wrote on Mon, Dec 18, 2023 at 08:54:13PM +0530:
commit that is causing build failure, drm/atomic: Pass the full state to CRTC atomic begin and flush [ Upstream commit f6ebe9f9c9233a6114eb922aba9a0c9ccc2d2e14 ]
I also had to fix up a few nxp-provided drivers because of this commits, it seems a bit heavy-handed for stable trees when users can have a couple of out of tree modules.
It's marked as a stable dep of fe4c5f662097 ("drm/mediatek: Add spinlock for setting vblank event in atomic_begin") but that looks like it's only because of the context and it should be easy to backport that commit without the crtc atomic begin/flush rework -- what do you think?
On Tue, Dec 19, 2023 at 09:54:45AM +0900, Dominique Martinet wrote:
Naresh Kamboju wrote on Mon, Dec 18, 2023 at 08:54:13PM +0530:
commit that is causing build failure, drm/atomic: Pass the full state to CRTC atomic begin and flush [ Upstream commit f6ebe9f9c9233a6114eb922aba9a0c9ccc2d2e14 ]
I also had to fix up a few nxp-provided drivers because of this commits, it seems a bit heavy-handed for stable trees when users can have a couple of out of tree modules.
It's marked as a stable dep of fe4c5f662097 ("drm/mediatek: Add spinlock for setting vblank event in atomic_begin") but that looks like it's only because of the context and it should be easy to backport that commit without the crtc atomic begin/flush rework -- what do you think?
Good catch, I've dropped those two larger dependent patches now and fixed up the spinlock patch by hand to work properly.
I'll push out a -rc2 now, thanks!
greg k-h
On 12/18/23 06:51, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.10.205 release. There are 62 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 20 Dec 2023 13:50:31 +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.205-rc... 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
Still doesn't boot on my test system. I am getting closer to finding the problem. The combination of ZSTD config options and compressed amdgpu firmware seems to be the trigger. I did find null pointer deferenece in amdgpu_gfx_rlc_setup_cp_table() related to compressed mce2_fw when renoir_mec2.bin load fails.
This fix will be in mainline - I still have to find why I don't see the null reference problem on mainline and all other stables. It could be that it is taking a different path to get to this point on 5.10 when renoir_mec2.bin is compressed.
I will keep you updated.
thanks, -- Shuah
linux-stable-mirror@lists.linaro.org