6.10.10-rc1 review
Subsystems (8)
Greg Kroah-Hartman
maintainerPATCH 132/375 fs: dont copy to userspace under namespace semaphore
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit cb54ef4f050e7c504ed87114276a296d727e918a ]
Don't copy mount ids to userspace while holding the namespace semaphore. We really shouldn't do that and I've gone through lenghts avoiding that in statmount() already.
Limit the number of mounts that can be retrieved in one go to 1 million mount ids. That's effectively 10 times the default limt of 100000 mounts that we put on each mount namespace by default. Since listmount() is an iterator limiting the number of mounts retrievable in one go isn't a problem as userspace can just pick up where they left off.
Karel menti_ned that libmount will probably be reading the mount table in "in small steps, 512 nodes per request. Nobody likes a tool that takes too long in the kernel, and huge servers are unusual use cases. Libmount will very probably provide API to define size of the step (IDs per request)."
--- fs/namespace.c | 98 ++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 42 deletions(-)
fs/namespace.c +56 -42
@@ -5047,55 +5047,81 @@ static struct mount *listmnt_next(struct mount *curr)return node_to_mount (rb_next (&curr->mnt_node)); } -static ssize_t do_listmount (struct mount *first,struct path *orig, -u64 mnt_parent_id,u64 __user *mnt_ids, -size_t nr_mnt_ids,const struct path *root) +static ssize_t do_listmount (u64 mnt_parent_id,u64 last_mnt_id,u64 *mnt_ids, +size_t nr_mnt_ids) { -struct mount *r; +struct path root; +struct mnt_namespace *ns = current->nsproxy->mnt_ns; +struct path orig; +struct mount *r, *first;ssize_t ret; +rwsem_assert_held (&namespace_sem); + +get_fs_root (current->fs, &root); +if (mnt_parent_id ==LSMT_ROOT ) { + orig = root; + }else { + orig.mnt =lookup_mnt_in_ns (mnt_parent_id, ns); +if (!orig.mnt) { + ret = -ENOENT ; + goto err; + } + orig.dentry = orig.mnt->mnt_root; + } +/* * Don't trigger audit denials. We just want to determine what * mounts to show users. */ -if (!is_path_reachable (real_mount (orig->mnt), orig->dentry, root) && - !ns_capable_noaudit (&init_user_ns,CAP_SYS_ADMIN )) -return -EPERM ; +if (!is_path_reachable (real_mount (orig.mnt), orig.dentry, &root) && + !ns_capable_noaudit (&init_user_ns,CAP_SYS_ADMIN )) { + ret = -EPERM ; + goto err; + } - ret =security_sb_statfs (orig->dentry); + ret =security_sb_statfs (orig.dentry);if (ret) -return ret; + goto err; + +if (!last_mnt_id) + first =node_to_mount (rb_first (&ns->mounts)); +else + first =mnt_find_id_at (ns, last_mnt_id +1 );for (ret =0 , r = first; r && nr_mnt_ids; r =listmnt_next (r)) {if (r->mnt_id_unique == mnt_parent_id)continue ; -if (!is_path_reachable (r, r->mnt.mnt_root, orig)) +if (!is_path_reachable (r, r->mnt.mnt_root, &orig))continue ; -if (put_user (r->mnt_id_unique, mnt_ids)) -return -EFAULT ; + *mnt_ids = r->mnt_id_unique; mnt_ids++; nr_mnt_ids--; ret++; } +err: +path_put (&root);return ret; } -SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, u64 __user *, - mnt_ids, size_t, nr_mnt_ids, unsigned int, flags) +SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, + u64 __user *, mnt_ids, size_t, nr_mnt_ids, unsigned int, flags) { -struct mnt_namespace *ns = current->nsproxy->mnt_ns; + u64 *kmnt_ids __free(kvfree) = NULL; +const size_t maxcount =1000000 ;struct mnt_id_req kreq; -struct mount *first; -struct path root, orig; -u64 mnt_parent_id, last_mnt_id; -const size_t maxcount = (size_t )-1 >>3 ;ssize_t ret;if (flags)return -EINVAL ; +/* +* If the mount namespace really has more than 1 million mounts the +* caller must iterate over the mount namespace (and reconsider their +* system design...). +*/ if (unlikely (nr_mnt_ids > maxcount)) -return -EFAULT ; +return -EOVERFLOW ;if (!access_ok (mnt_ids, nr_mnt_ids *sizeof (*mnt_ids)))return -EFAULT ;
@@ -5103,33 +5129,21 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req, u64 __user *, ret =copy_mnt_id_req (req, &kreq);if (ret)return ret; - mnt_parent_id = kreq.mnt_id; - last_mnt_id = kreq.param; -down_read (&namespace_sem); -get_fs_root (current->fs, &root); -if (mnt_parent_id ==LSMT_ROOT ) { - orig = root; - }else { - ret = -ENOENT ; - orig.mnt =lookup_mnt_in_ns (mnt_parent_id, ns); -if (!orig.mnt) - goto err; - orig.dentry = orig.mnt->mnt_root; - } -if (!last_mnt_id) - first =node_to_mount (rb_first (&ns->mounts)); -else - first =mnt_find_id_at (ns, last_mnt_id +1 ); + kmnt_ids =kvmalloc_array (nr_mnt_ids,sizeof (*kmnt_ids), +GFP_KERNEL_ACCOUNT ); +if (!kmnt_ids) +return -ENOMEM ; + +scoped_guard (rwsem_read, &namespace_sem) + ret = do_listmount(kreq.mnt_id, kreq.param, kmnt_ids, nr_mnt_ids); + +if (copy_to_user (mnt_ids, kmnt_ids, ret *sizeof (*mnt_ids))) +return -EFAULT ; - ret =do_listmount (first, &orig, mnt_parent_id, mnt_ids, nr_mnt_ids, &root); -err: -path_put (&root); -up_read (&namespace_sem);return ret; } -static void __init init_mount_tree (void ) {struct vfsmount *mnt;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 133/375 fs: relax permissions for statmount()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <[email protected]>
[ Upstream commit f3107df39df123328a9d3c8f40c006834b37287d ]
It is sufficient to have capabilities in the owning user namespace of the mount namespace to stat a mount regardless of whether it's reachable or not.
--- fs/namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/namespace.c +2 -1
@@ -4906,6 +4906,7 @@ static int copy_statmount_to_user(struct kstatmount *s)static int do_statmount (struct kstatmount *s) {struct mount *m =real_mount (s->mnt); +struct mnt_namespace *ns = m->mnt_ns;int err;/*
@@ -4913,7 +4914,7 @@ static int do_statmount(struct kstatmount *s)* mounts to show users. */ if (!is_path_reachable (m, m->mnt.mnt_root, &s->root) && - !ns_capable_noaudit (&init_user_ns,CAP_SYS_ADMIN )) + !ns_capable_noaudit (ns->user_ns,CAP_SYS_ADMIN ))return -EPERM ; err =security_sb_statfs (s->mnt->mnt_root);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 134/375 powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Lynch <[email protected]>
[ Upstream commit 0974d03eb479384466d828d65637814bee6b26d7 ]
Smatch warns:
arch/powerpc/kernel/rtas.c:1932 __do_sys_rtas() warn: potential spectre issue 'args.args' [r] (local cap)
The 'nargs' and 'nret' locals come directly from a user-supplied buffer and are used as indexes into a small stack-based array and as inputs to copy_to_user() after they are subject to bounds checks.
Use array_index_nospec() after the bounds checks to clamp these values for speculative execution.
--- arch/powerpc/kernel/rtas.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/powerpc/kernel/rtas.c +4 -0
@@ -19,6 +19,7 @@#include <linux/lockdep.h> #include <linux/memblock.h> #include <linux/mutex.h> +#include <linux/nospec.h> #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/reboot.h>
@@ -1916,6 +1917,9 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) || nargs + nret > ARRAY_SIZE(args.args))return -EINVAL ; + nargs =array_index_nospec (nargs,ARRAY_SIZE (args.args)); + nret =array_index_nospec (nret,ARRAY_SIZE (args.args) - nargs); +/* Copy in args. */ if (copy_from_user (args.args, uargs->args, nargs *sizeof (rtas_arg_t)) !=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 135/375 seccomp: release task filters when the task exits
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Vagin <[email protected]>
[ Upstream commit bfafe5efa9754ebc991750da0bcca2a6694f3ed3 ]
Previously, seccomp filters were released in release_task(), which required the process to exit and its zombie to be collected. However, exited threads/processes can't trigger any seccomp events, making it more logical to release filters upon task exits.
This adjustment simplifies scenarios where a parent is tracing its child process. The parent process can now handle all events from a seccomp listening descriptor and then call wait to collect a child zombie.
seccomp_filter_release takes the siglock to avoid races with seccomp_sync_threads. There was an idea to bypass taking the lock by checking PF_EXITING, but it can be set without holding siglock if threads have SIGNAL_GROUP_EXIT. This means it can happen concurently with seccomp_filter_release.
This change also fixes another minor problem. Suppose that a group leader installs the new filter without SECCOMP_FILTER_FLAG_TSYNC, exits, and becomes a zombie. Without this change, SECCOMP_FILTER_FLAG_TSYNC from any other thread can never succeed, seccomp_can_sync_threads() will check a zombie leader and is_ancestor() will fail.
--- kernel/exit.c | 3 ++- kernel/seccomp.c | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-)
kernel/exit.c +2 -1
@@ -277,7 +277,6 @@ void release_task(struct task_struct *p) }write_unlock_irq (&tasklist_lock); -seccomp_filter_release (p);proc_flush_pid (thread_pid);put_pid (thread_pid);release_thread (p);
@@ -834,6 +833,8 @@ void __noreturn do_exit(long code)io_uring_files_cancel ();exit_signals (tsk);/* sets PF_EXITING */ +seccomp_filter_release (tsk); +acct_update_integrals (tsk); group_dead =atomic_dec_and_test (&tsk->signal->live);if (group_dead) {
kernel/seccomp.c +18 -5
@@ -502,6 +502,9 @@ static inline pid_t seccomp_can_sync_threads(void)/* Skip current, since it is initiating the sync. */ if (thread == caller)continue ; +/* Skip exited threads. */ +if (thread->flags &PF_EXITING ) +continue ; if (thread->seccomp.mode == SECCOMP_MODE_DISABLED || (thread->seccomp.mode == SECCOMP_MODE_FILTER &&
@@ -563,18 +566,21 @@ static void __seccomp_filter_release(struct seccomp_filter *orig)* @tsk: task the filter should be released from. * * This function should only be called when the task is exiting as -* it detaches it from its filter tree. As such, READ_ONCE() and -* barriers are not needed here, as would normally be needed. +* it detaches it from its filter tree. PF_EXITING has to be set +* for the task. */ void seccomp_filter_release (struct task_struct *tsk) { -struct seccomp_filter *orig = tsk->seccomp.filter; +struct seccomp_filter *orig; -/* We are effectively holding the siglock by not having any sighand. */ -WARN_ON (tsk->sighand !=NULL ); +if (WARN_ON ((tsk->flags &PF_EXITING ) ==0 )) +return ; +spin_lock_irq (&tsk->sighand->siglock); + orig = tsk->seccomp.filter;/* Detach task from its filter tree. */ tsk->seccomp.filter =NULL ; +spin_unlock_irq (&tsk->sighand->siglock);__seccomp_filter_release (orig); }
@@ -602,6 +608,13 @@ static inline void seccomp_sync_threads(unsigned long flags)if (thread == caller)continue ; +/* +* Skip exited threads. seccomp_filter_release could have +* been already called for this task. +*/ +if (thread->flags &PF_EXITING ) +continue ; +/* Get a task reference for the new leaf node. */ get_seccomp_filter (caller);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 136/375 ice: Check all ice_vsi_rebuild() errors in function
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Joyner <[email protected]>
[ Upstream commit d47bf9a495cf424fad674321d943123dc12b926d ]
Check the return value from ice_vsi_rebuild() and prevent the usage of incorrectly configured VSI.
--- drivers/net/ethernet/intel/ice/ice_main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/ice/ice_main.c +11 -2
@@ -4160,13 +4160,17 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked)/* set for the next time the netdev is started */ if (!netif_running (vsi->netdev)) { -ice_vsi_rebuild (vsi,ICE_VSI_FLAG_NO_INIT ); + err =ice_vsi_rebuild (vsi,ICE_VSI_FLAG_NO_INIT ); +if (err) + goto rebuild_err;dev_dbg (ice_pf_to_dev (pf),"Link is down, queue count change happens when link is brought up\n" ); goto done; }ice_vsi_close (vsi); -ice_vsi_rebuild (vsi,ICE_VSI_FLAG_NO_INIT ); + err =ice_vsi_rebuild (vsi,ICE_VSI_FLAG_NO_INIT ); +if (err) + goto rebuild_err;ice_for_each_traffic_class (i) {if (vsi->tc_cfg.ena_tc &BIT (i))
@@ -4177,6 +4181,11 @@ int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked) }ice_pf_dcb_recfg (pf, locked);ice_vsi_open (vsi); + goto done; + +rebuild_err: +dev_err (ice_pf_to_dev (pf),"Error during VSI rebuild: %d. Unload and reload the driver.\n" , + err); done:clear_bit (ICE_CFG_BUSY , pf->state);return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 137/375 PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kishon Vijay Abraham I <[email protected]>
[ Upstream commit 86f271f22bbb6391410a07e08d6ca3757fda01fa ]
Errata #i2037 in AM65x/DRA80xM Processors Silicon Revision 1.0 (SPRZ452D_July 2018_Revised December 2019 [1]) mentions when an inbound PCIe TLP spans more than two internal AXI 128-byte bursts, the bus may corrupt the packet payload and the corrupt data may cause associated applications or the processor to hang.
The workaround for Errata #i2037 is to limit the maximum read request size and maximum payload size to 128 bytes. Add workaround for Errata #i2037 here.
The errata and workaround is applicable only to AM65x SR 1.0 and later versions of the silicon will have this fixed.
[1] -> https://www.ti.com/lit/er/sprz452i/sprz452i.pdf
--- drivers/pci/controller/dwc/pci-keystone.c | 44 ++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pci-keystone.c +43 -1
@@ -34,6 +34,11 @@#define PCIE_DEVICEID_SHIFT 16/* Application registers */ +#define PID 0x000 +#define RTL GENMASK(15, 11) +#define RTL_SHIFT 11 +#define AM6_PCI_PG1_RTL_VER 0x15 +#define CMD_STATUS 0x004#define LTSSM_EN_VAL BIT(0)#define OB_XLAT_EN_VAL BIT(1)
@@ -104,6 +109,8 @@#define to_keystone_pcie (x) dev_get_drvdata((x)->dev) +#define PCI_DEVICE_ID_TI_AM654X 0xb00c +struct ks_pcie_of_data {enum dw_pcie_device_mode mode;const struct dw_pcie_host_ops *host_ops;
@@ -516,7 +523,11 @@ static int ks_pcie_start_link(struct dw_pcie *pci)static void ks_pcie_quirk (struct pci_dev *dev) {struct pci_bus *bus = dev->bus; +struct keystone_pcie *ks_pcie; +struct device *bridge_dev;struct pci_dev *bridge; +u32 val; +static const struct pci_device_id rc_pci_devids[] = { {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCIE_RC_K2HK ), .class =PCI_CLASS_BRIDGE_PCI_NORMAL , .class_mask = ~0 , },
@@ -528,6 +539,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) .class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0, }, { 0, }, }; +static const struct pci_device_id am6_pci_devids[] = { + {PCI_DEVICE (PCI_VENDOR_ID_TI ,PCI_DEVICE_ID_TI_AM654X ), + .class =PCI_CLASS_BRIDGE_PCI <<8 , .class_mask = ~0 , }, + {0 , }, + };if (pci_is_root_bus (bus)) bridge = dev;
@@ -549,10 +565,36 @@ static void ks_pcie_quirk(struct pci_dev *dev)*/ if (pci_match_id (rc_pci_devids, bridge)) {if (pcie_get_readrq (dev) >256 ) { -dev_info (&dev->dev,"limiting MRRS to 256\n" ); +dev_info (&dev->dev,"limiting MRRS to 256 bytes\n" );pcie_set_readrq (dev,256 ); } } + +/* +* Memory transactions fail with PCI controller in AM654 PG1.0 +* when MRRS is set to more than 128 bytes. Force the MRRS to +* 128 bytes in all downstream devices. +*/ +if (pci_match_id (am6_pci_devids, bridge)) { + bridge_dev =pci_get_host_bridge_device (dev); +if (!bridge_dev && !bridge_dev->parent) +return ; + + ks_pcie =dev_get_drvdata (bridge_dev->parent); +if (!ks_pcie) +return ; + + val =ks_pcie_app_readl (ks_pcie,PID ); + val &=RTL ; + val >>=RTL_SHIFT ; +if (val !=AM6_PCI_PG1_RTL_VER ) +return ; + +if (pcie_get_readrq (dev) >128 ) { +dev_info (&dev->dev,"limiting MRRS to 128 bytes\n" ); +pcie_set_readrq (dev,128 ); + } + } }DECLARE_PCI_FIXUP_ENABLE (PCI_ANY_ID ,PCI_ANY_ID , ks_pcie_quirk);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 138/375 Input: ili210x - use kvmalloc() to allocate buffer for firmware update
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
[ Upstream commit 17f5eebf6780eee50f887542e1833fda95f53e4d ]
Allocating a contiguous buffer of 64K may fail if memory is sufficiently fragmented, and may cause OOM kill of an unrelated process. However we do not need to have contiguous memory. We also do not need to zero out the buffer since it will be overwritten with firmware data.
Switch to using kvmalloc() instead of kzalloc().
--- drivers/input/touchscreen/ili210x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/input/touchscreen/ili210x.c +3 -3
@@ -597,7 +597,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,* once, copy them all into this buffer at the right locations, and then * do all operations on this linear buffer. */ - fw_buf =kzalloc (SZ_64K ,GFP_KERNEL ); + fw_buf =kvmalloc (SZ_64K ,GFP_KERNEL );if (!fw_buf)return -ENOMEM ;
@@ -627,7 +627,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,return 0 ; err_big: -kfree (fw_buf); +kvfree (fw_buf);return error; }
@@ -870,7 +870,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,ili210x_hardware_reset (priv->reset_gpio);dev_dbg (dev,"Firmware update ended, error=%i\n" , error);enable_irq (client->irq); -kfree (fwbuf); +kvfree (fwbuf);return error; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 139/375 media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni <[email protected]>
[ Upstream commit 4caf6d93d9f2c11d6441c64e1c549c445fa322ed ]
Add check for the return value of v4l2_fwnode_endpoint_parse() and return the error if it fails in order to catch the error.
--- drivers/media/platform/qcom/camss/camss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/media/platform/qcom/camss/camss.c +4 -1
@@ -1406,8 +1406,11 @@ static int camss_of_parse_endpoint_node(struct device *dev,struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;struct v4l2_fwnode_endpoint vep = { {0 } };unsigned int i; +int ret; -v4l2_fwnode_endpoint_parse (of_fwnode_handle (node), &vep); + ret =v4l2_fwnode_endpoint_parse (of_fwnode_handle (node), &vep); +if (ret) +return ret; csd->interface.csiphy_id = vep.base.port;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 140/375 pcmcia: Use resource_size function on resource object
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jules Irenge <[email protected]>
[ Upstream commit 24a025497e7e883bd2adef5d0ece1e9b9268009f ]
Cocinnele reports a warning
WARNING: Suspicious code. resource_size is maybe missing with root
The root cause is the function resource_size is not used when needed
Use resource_size() on variable "root" of type resource
--- drivers/pcmcia/yenta_socket.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/pcmcia/yenta_socket.c +3 -3
@@ -638,11 +638,11 @@ static int yenta_search_one_res(struct resource *root, struct resource *res, start =PCIBIOS_MIN_CARDBUS_IO ; end = ~0U ; }else { -unsigned long avail = root->end - root->start; +unsigned long avail =resource_size (root);int i; size =BRIDGE_MEM_MAX ; -if (size > avail/8 ) { - size = (avail+1 )/8 ; +if (size > (avail -1 ) /8 ) { + size = avail /8 ;/* round size down to next power of 2 */ i =0 ;while ((size /=2 ) !=0 )
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 141/375 drm/amd/display: Check denominator pbn_div before used
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit 116a678f3a9abc24f5c9d2525b7393d18d9eb58e ]
[WHAT & HOW]
A denominator cannot be 0, and is checked before used.
This fixes 1 DIVIDE_BY_ZERO issue reported by Coverity.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -7302,7 +7302,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, } } -if (j == dc_state->stream_count) +if (j == dc_state->stream_count || pbn_div ==0 )continue ; slot_num =DIV_ROUND_UP (pbn, pbn_div);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 142/375 drm/amd/display: Check denominator crb_pipes before used
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <[email protected]>
[ Upstream commit ea79068d4073bf303f8203f2625af7d9185a1bc6 ]
[WHAT & HOW]
A denominator cannot be 0, and is checked before used.
This fixes 2 DIVIDE_BY_ZERO issues reported by Coverity.
--- .../gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +1 -1
@@ -1756,7 +1756,7 @@ static int dcn315_populate_dml_pipes_from_context(bool split_required = pipe->stream->timing.pix_clk_100hz >=dcn_get_max_non_odm_pix_rate_100hz (&dc->dml.soc) || (pipe->plane_state && pipe->plane_state->src_rect.width >5120 ); -if (remaining_det_segs >MIN_RESERVED_DET_SEGS ) +if (remaining_det_segs >MIN_RESERVED_DET_SEGS && crb_pipes !=0 ) pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs -MIN_RESERVED_DET_SEGS ) / crb_pipes + (crb_idx < (remaining_det_segs -MIN_RESERVED_DET_SEGS ) % crb_pipes ?1 :0 );if (pipes[pipe_cnt].pipe.src.det_size_override >2 *DCN3_15_MAX_DET_SEGS ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 143/375 drm/amdgpu: check for LINEAR_ALIGNED correctly in check_tiling_flags_gfx6
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Olšák <[email protected]>
[ Upstream commit 11317d2963fa79767cd7c6231a00a9d77f2e0f54 ]
Fix incorrect check.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +1 -2
@@ -917,8 +917,7 @@ static int check_tiling_flags_gfx6(struct amdgpu_framebuffer *afb) {u64 micro_tile_mode; -/* Zero swizzle mode means linear */ -if (AMDGPU_TILING_GET (afb->tiling_flags,SWIZZLE_MODE ) ==0 ) +if (AMDGPU_TILING_GET (afb->tiling_flags,ARRAY_MODE ) ==1 )/* LINEAR_ALIGNED */ return 0 ; micro_tile_mode =AMDGPU_TILING_GET (afb->tiling_flags,MICRO_TILE_MODE );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 144/375 drm/amdgpu: Correct register used to clear fault status
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hawking Zhang <[email protected]>
[ Upstream commit c2fad7317441be573175c4d98b28347ddec7fe77 ]
Driver should write to fault_cntl registers to do one-shot address/status clear.
--- drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c +1 -1
@@ -569,7 +569,7 @@ static bool mmhub_v1_8_query_utcl2_poison_status(struct amdgpu_device *adev,if (!amdgpu_sriov_vf (adev)) {/* clear page fault status and address */ WREG32_P (SOC15_REG_OFFSET (MMHUB , hub_inst, - regVM_L2_PROTECTION_FAULT_STATUS),1 , ~1 ); + regVM_L2_PROTECTION_FAULT_CNTL),1 , ~1 ); }return fed;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 145/375 drm/amdgpu/display: handle gfx12 in amdgpu_dm_plane_format_mod_supported
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Olšák <[email protected]>
[ Upstream commit ed17b63e7e25f03b40db66a8d5802b89aac40441 ]
All this code has undefined behavior on GFX12 and shouldn't be executed.
--- .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +25 -22
@@ -1400,8 +1400,6 @@ static bool amdgpu_dm_plane_format_mod_supported(struct drm_plane *plane,const struct drm_format_info *info =drm_format_info (format);int i; -enum dm_micro_swizzle microtile =amdgpu_dm_plane_modifier_gfx9_swizzle_mode (modifier) &3 ; -if (!info)return false;
@@ -1423,29 +1421,34 @@ static bool amdgpu_dm_plane_format_mod_supported(struct drm_plane *plane,if (i == plane->modifier_count)return false; -/* -* For D swizzle the canonical modifier depends on the bpp, so check -* it here. -*/ -if (AMD_FMT_MOD_GET (TILE_VERSION , modifier) ==AMD_FMT_MOD_TILE_VER_GFX9 && - adev->family >=AMDGPU_FAMILY_NV ) { -if (microtile ==MICRO_SWIZZLE_D && info->cpp[0 ] ==4 ) -return false; - } - -if (adev->family >=AMDGPU_FAMILY_RV && microtile ==MICRO_SWIZZLE_D && - info->cpp[0 ] <8 ) -return false; +/* GFX12 doesn't have these limitations. */ +if (AMD_FMT_MOD_GET (TILE_VERSION , modifier) <=AMD_FMT_MOD_TILE_VER_GFX11 ) { +enum dm_micro_swizzle microtile =amdgpu_dm_plane_modifier_gfx9_swizzle_mode (modifier) &3 ; -if (amdgpu_dm_plane_modifier_has_dcc (modifier)) { -/* Per radeonsi comments 16/64 bpp are more complicated. */ -if (info->cpp[0 ] !=4 ) -return false; -/* We support multi-planar formats, but not when combined with -* additional DCC metadata planes. +/* +* For D swizzle the canonical modifier depends on the bpp, so check +* it here. */ -if (info->num_planes >1 ) +if (AMD_FMT_MOD_GET (TILE_VERSION , modifier) ==AMD_FMT_MOD_TILE_VER_GFX9 && + adev->family >=AMDGPU_FAMILY_NV ) { +if (microtile ==MICRO_SWIZZLE_D && info->cpp[0 ] ==4 ) +return false; + } + +if (adev->family >=AMDGPU_FAMILY_RV && microtile ==MICRO_SWIZZLE_D && + info->cpp[0 ] <8 )return false; + +if (amdgpu_dm_plane_modifier_has_dcc (modifier)) { +/* Per radeonsi comments 16/64 bpp are more complicated. */ +if (info->cpp[0 ] !=4 ) +return false; +/* We support multi-planar formats, but not when combined with +* additional DCC metadata planes. +*/ +if (info->num_planes >1 ) +return false; + } }return true;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 146/375 can: bcm: Remove proc entry when dev is unregistered.
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 76fe372ccb81b0c89b6cd2fec26e2f38c958be85 ]
syzkaller reported a warning in bcm_connect() below. [0]
The repro calls connect() to vxcan1, removes vxcan1, and calls connect() with ifindex == 0.
Calling connect() for a BCM socket allocates a proc entry. Then, bcm_sk(sk)->bound is set to 1 to prevent further connect().
However, removing the bound device resets bcm_sk(sk)->bound to 0 in bcm_notify().
The 2nd connect() tries to allocate a proc entry with the same name and sets NULL to bcm_sk(sk)->bcm_proc_read, leaking the original proc entry.
Since the proc entry is available only for connect()ed sockets, let's clean up the entry when the bound netdev is unregistered.
[0]:proc_dir_entry 'can-bcm/2456' already registered
WARNING: CPU: 1 PID: 394 at fs/proc/generic.c:376 proc_register+0x645/0x8f0 fs/proc/generic.c:375 Modules linked in: CPU: 1 PID: 394 Comm: syz-executor403 Not tainted 6.10.0-rc7-g852e42cc2dd4 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 RIP: 0010:proc_register+0x645/0x8f0 fs/proc/generic.c:375 Code: 00 00 00 00 00 48 85 ed 0f 85 97 02 00 00 4d 85 f6 0f 85 9f 02 00 00 48 c7 c7 9b cb cf 87 48 89 de 4c 89 fa e8 1c 6f eb fe 90 <0f> 0b 90 90 48 c7 c7 98 37 99 89 e8 cb 7e 22 05 bb 00 00 00 10 48 RSP: 0018:ffa0000000cd7c30 EFLAGS: 00010246 RAX: 9e129be1950f0200 RBX: ff1100011b51582c RCX: ff1100011857cd80 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000002 RBP: 0000000000000000 R08: ffd400000000000f R09: ff1100013e78cac0 R10: ffac800000cd7980 R11: ff1100013e12b1f0 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: ff1100011a99a2ec FS: 00007fbd7086f740(0000) GS:ff1100013fd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000200071c0 CR3: 0000000118556004 CR4: 0000000000771ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> proc_create_net_single+0x144/0x210 fs/proc/proc_net.c:220 bcm_connect+0x472/0x840 net/can/bcm.c:1673 __sys_connect_file net/socket.c:2049 [inline] __sys_connect+0x5d2/0x690 net/socket.c:2066 __do_sys_connect net/socket.c:2076 [inline] __se_sys_connect net/socket.c:2073 [inline] __x64_sys_connect+0x8f/0x100 net/socket.c:2073 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xd9/0x1c0 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7fbd708b0e5d Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 73 9f 1b 00 f7 d8 64 89 01 48 RSP: 002b:00007fff8cd33f08 EFLAGS: 00000246 ORIG_RAX: 000000000000002a RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fbd708b0e5d RDX: 0000000000000010 RSI: 0000000020000040 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000000000040 R09: 0000000000000040 R10: 0000000000000040 R11: 0000000000000246 R12: 00007fff8cd34098 R13: 0000000000401280 R14: 0000000000406de8 R15: 00007fbd70ab9000 </TASK>
remove_proc_entry: removing non-empty directory 'net/can-bcm', leaking at least '2456'
--- net/can/bcm.c | 4 ++++ 1 file changed, 4 insertions(+)
net/can/bcm.c +4 -0
@@ -1470,6 +1470,10 @@ static void bcm_notify(struct bcm_sock *bo, unsigned long msg,/* remove device reference, if this is our bound device */ if (bo->bound && bo->ifindex == dev->ifindex) { +#if IS_ENABLED (CONFIG_PROC_FS ) +if (sock_net (sk)->can.bcmproc_dir && bo->bcm_proc_read) +remove_proc_entry (bo->procname,sock_net (sk)->can.bcmproc_dir); +#endif bo->bound =0 ; bo->ifindex =0 ; notify_enodev =1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 147/375 can: m_can: Release irq on error in m_can_open
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman <[email protected]>
[ Upstream commit 06d4ef3056a7ac31be331281bb7a6302ef5a7f8a ]
It appears that the irq requested in m_can_open() may be leaked if an error subsequently occurs: if m_can_start() fails.
Address this by calling free_irq in the unwind path for such cases.
Flagged by Smatch.
Compile tested only.
--- drivers/net/can/m_can/m_can.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/can/m_can/m_can.c +4 -1
@@ -2009,7 +2009,7 @@ static int m_can_open(struct net_device *dev)/* start the m_can controller */ err =m_can_start (dev);if (err) - goto exit_irq_fail; + goto exit_start_fail;if (!cdev->is_peripheral)napi_enable (&cdev->napi);
@@ -2018,6 +2018,9 @@ static int m_can_open(struct net_device *dev)return 0 ; +exit_start_fail: +if (cdev->is_peripheral || dev->irq) +free_irq (dev->irq, dev); exit_irq_fail:if (cdev->is_peripheral)destroy_workqueue (cdev->tx_wq);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 148/375 can: m_can: Reset coalescing during suspend/resume
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit a651261ac74298535f6d6316ebe27beceb6b17b1 ]
During resume the interrupts are limited to IR_RF0N and the chip keeps running. In this case if coalescing is enabled and active we may miss waterlevel interrupts during suspend. It is safer to reset the coalescing by stopping the timer and adding IR_RF0N | IR_TEFN to the interrupts.
This is a theoratical issue and probably extremely rare.
--- drivers/net/can/m_can/m_can.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/net/can/m_can/m_can.c +13 -3
@@ -2387,12 +2387,15 @@ int m_can_class_suspend(struct device *dev)netif_device_detach (ndev);/* leave the chip running with rx interrupt enabled if it is -* used as a wake-up source. +* used as a wake-up source. Coalescing needs to be reset then, +* the timer is cancelled here, interrupts are done in resume. */ -if (cdev->pm_wake_source) +if (cdev->pm_wake_source) { +hrtimer_cancel (&cdev->hrtimer);m_can_write (cdev,M_CAN_IE ,IR_RF0N ); -else + }else {m_can_stop (ndev); + }m_can_clk_stop (cdev); }
@@ -2422,6 +2425,13 @@ int m_can_class_resume(struct device *dev)return ret;if (cdev->pm_wake_source) { +/* Restore active interrupts but disable coalescing as +* we may have missed important waterlevel interrupts +* between suspend and resume. Timers are already +* stopped in suspend. Here we enable all interrupts +* again. +*/ + cdev->active_interrupts |=IR_RF0N |IR_TEFN ;m_can_write (cdev,M_CAN_IE , cdev->active_interrupts); }else { ret =m_can_start (ndev);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 149/375 can: m_can: Remove coalesing disable in isr during suspend
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit 6eff1cead75ff330bb33264424c1da6cc7179ab8 ]
We don't need to disable coalescing when the interrupt handler executes while the chip is suspended. The coalescing is already reset during suspend.
--- drivers/net/can/m_can/m_can.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/can/m_can/m_can.c +1 -3
@@ -1189,10 +1189,8 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)struct m_can_classdev *cdev =netdev_priv (dev);u32 ir; -if (pm_runtime_suspended (cdev->dev)) { -m_can_coalescing_disable (cdev); +if (pm_runtime_suspended (cdev->dev))return IRQ_NONE ; - } ir =m_can_read (cdev,M_CAN_IR );m_can_coalescing_update (cdev, ir);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 150/375 can: m_can: Remove m_can_rx_peripheral indirection
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit 40e4552eeef0e3090a5988de15889795936fd38f ]
m_can_rx_peripheral() is a wrapper around m_can_rx_handler() that calls m_can_disable_all_interrupts() on error. The same handling for the same error path is done in m_can_isr() as well.
So remove m_can_rx_peripheral() and do the call from m_can_isr() directly.
Stable-dep-of: 4d5159bfafa8 ("can: m_can: Do not cancel timer from within timer")
--- drivers/net/can/m_can/m_can.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
drivers/net/can/m_can/m_can.c +1 -17
@@ -1003,22 +1003,6 @@ static int m_can_rx_handler(struct net_device *dev, int quota, u32 irqstatus)return work_done; } -static int m_can_rx_peripheral (struct net_device *dev,u32 irqstatus) -{ -struct m_can_classdev *cdev =netdev_priv (dev); -int work_done; - - work_done =m_can_rx_handler (dev,NAPI_POLL_WEIGHT , irqstatus); - -/* Don't re-enable interrupts if the driver had a fatal error -* (e.g., FIFO read failure). -*/ -if (work_done <0 ) -m_can_disable_all_interrupts (cdev); - -return work_done; -} -static int m_can_poll (struct napi_struct *napi,int quota) {struct net_device *dev = napi->dev;
@@ -1216,7 +1200,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) }else {int pkts; - pkts =m_can_rx_peripheral (dev, ir); + pkts =m_can_rx_handler (dev,NAPI_POLL_WEIGHT , ir);if (pkts <0 ) goto out_fail; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 151/375 can: m_can: Do not cancel timer from within timer
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit 4d5159bfafa8d1a205d8213b7434e0402588b9ed ]
On setups without interrupts, the interrupt handler is called from a timer callback. For non-peripheral receives napi is scheduled, interrupts are disabled and the timer is canceled with a blocking call. In case of an error this can happen as well.
Check if napi is scheduled in the timer callback after the interrupt handler executed. If napi is scheduled, the timer is disabled. It will be reenabled by m_can_poll().
Return error values from the interrupt handler so that interrupt threads and timer callback can deal differently with it. In case of the timer we only disable the timer. The rest will be done when stopping the interface.
--- drivers/net/can/m_can/m_can.c | 57 ++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 15 deletions(-)
drivers/net/can/m_can/m_can.c +42 -15
@@ -453,7 +453,7 @@ static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev)if (!cdev->net->irq) {dev_dbg (cdev->dev,"Stop hrtimer\n" ); -hrtimer_cancel (&cdev->hrtimer); +hrtimer_try_to_cancel (&cdev->hrtimer); } }
@@ -1167,11 +1167,15 @@ static void m_can_coalescing_update(struct m_can_classdev *cdev, u32 ir) HRTIMER_MODE_REL); } -static irqreturn_t m_can_isr (int irq,void *dev_id) +/* This interrupt handler is called either from the interrupt thread or a +* hrtimer. This has implications like cancelling a timer won't be possible +* blocking. +*/ +static int m_can_interrupt_handler (struct m_can_classdev *cdev) { -struct net_device *dev = (struct net_device *)dev_id; -struct m_can_classdev *cdev =netdev_priv (dev); +struct net_device *dev = cdev->net;u32 ir; +int ret;if (pm_runtime_suspended (cdev->dev))return IRQ_NONE ;
@@ -1198,11 +1202,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)m_can_disable_all_interrupts (cdev);napi_schedule (&cdev->napi); }else { -int pkts; - - pkts =m_can_rx_handler (dev,NAPI_POLL_WEIGHT , ir); -if (pkts <0 ) - goto out_fail; + ret =m_can_rx_handler (dev,NAPI_POLL_WEIGHT , ir); +if (ret <0 ) +return ret; } }
@@ -1220,8 +1222,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) }else {if (ir & (IR_TEFN |IR_TEFW )) {/* New TX FIFO Element arrived */ -if (m_can_echo_tx_event (dev) !=0 ) - goto out_fail; + ret =m_can_echo_tx_event (dev); +if (ret !=0 ) +return ret; } }
@@ -1229,16 +1232,31 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)can_rx_offload_threaded_irq_finish (&cdev->offload);return IRQ_HANDLED ; +} -out_fail: -m_can_disable_all_interrupts (cdev); -return IRQ_HANDLED ; +static irqreturn_t m_can_isr (int irq,void *dev_id) +{ +struct net_device *dev = (struct net_device *)dev_id; +struct m_can_classdev *cdev =netdev_priv (dev); +int ret; + + ret =m_can_interrupt_handler (cdev); +if (ret <0 ) { +m_can_disable_all_interrupts (cdev); +return IRQ_HANDLED ; + } + +return ret; }static enum hrtimer_restart m_can_coalescing_timer (struct hrtimer *timer) { struct m_can_classdev *cdev = container_of(timer, struct m_can_classdev, hrtimer); +if (cdev->can.state ==CAN_STATE_BUS_OFF || + cdev->can.state ==CAN_STATE_STOPPED ) +return HRTIMER_NORESTART ; +irq_wake_thread (cdev->net->irq, cdev->net);return HRTIMER_NORESTART ;
@@ -1930,8 +1948,17 @@ static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer) { struct m_can_classdev *cdev = container_of(timer, struct m_can_classdev, hrtimer); +int ret; + +if (cdev->can.state ==CAN_STATE_BUS_OFF || + cdev->can.state ==CAN_STATE_STOPPED ) +return HRTIMER_NORESTART ; + + ret =m_can_interrupt_handler (cdev); -m_can_isr (0 , cdev->net); +/* On error or if napi is scheduled to read, stop the timer */ +if (ret <0 ||napi_is_scheduled (&cdev->napi)) +return HRTIMER_NORESTART ;hrtimer_forward_now (timer,ms_to_ktime (HRTIMER_POLL_INTERVAL_MS ));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 152/375 can: m_can: disable_all_interrupts, not clear active_interrupts
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit a572fea86c9b06cd3e6e89d79d565b52cb7e7cff ]
active_interrupts is a cache for the enabled interrupts and not the global masking of interrupts. Do not clear this variable otherwise we may loose the state of the interrupts.
--- drivers/net/can/m_can/m_can.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/can/m_can/m_can.c +0 -1
@@ -449,7 +449,6 @@ static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev) {m_can_coalescing_disable (cdev);m_can_write (cdev,M_CAN_ILE ,0x0 ); - cdev->active_interrupts =0x0 ;if (!cdev->net->irq) {dev_dbg (cdev->dev,"Stop hrtimer\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 153/375 can: m_can: Reset cached active_interrupts on start
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit 733dbf556cd5b71d5e6f6aa7a93f117b438ab785 ]
To force writing the enabled interrupts, reset the active_interrupts cache.
--- drivers/net/can/m_can/m_can.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/can/m_can/m_can.c +1 -0
@@ -1505,6 +1505,7 @@ static int m_can_chip_config(struct net_device *dev)else interrupts &= ~(IR_ERR_LEC_31X ); } + cdev->active_interrupts =0 ;m_can_interrupt_enable (cdev, interrupts);/* route all interrupts to INT0 */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 154/375 can: mcp251xfd: fix ring configuration when switching from CAN-CC to CAN-FD mode
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
[ Upstream commit 50ea5449c56310d2d31c28ba91a59232116d3c1e ]
If the ring (rx, tx) and/or coalescing parameters (rx-frames-irq, tx-frames-irq) have been configured while the interface was in CAN-CC mode, but the interface is brought up in CAN-FD mode, the ring parameters might be too big.
Use the default CAN-FD values in this case.
--- drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c | 11 +++++++++- .../net/can/spi/mcp251xfd/mcp251xfd-ring.c | 20 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c +10 -1
@@ -97,7 +97,16 @@ void can_ram_get_layout(struct can_ram_layout *layout,if (ring) {u8 num_rx_coalesce =0 , num_tx_coalesce =0 ; - num_rx =can_ram_rounddown_pow_of_two (config, &config->rx,0 , ring->rx_pending); +/* If the ring parameters have been configured in +* CAN-CC mode, but and we are in CAN-FD mode now, +* they might be to big. Use the default CAN-FD values +* in this case. +*/ + num_rx = ring->rx_pending; +if (num_rx > layout->max_rx) + num_rx = layout->default_rx; + + num_rx =can_ram_rounddown_pow_of_two (config, &config->rx,0 , num_rx);/* The ethtool doc says: * To disable coalescing, set usecs = 0 and max_frames = 1.
drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c +17 -3
@@ -468,11 +468,25 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv)/* switching from CAN-2.0 to CAN-FD mode or vice versa */ if (fd_mode !=test_bit (MCP251XFD_FLAGS_FD_MODE , priv->flags)) { +const struct ethtool_ringparam ring = { + .rx_pending = priv->rx_obj_num, + .tx_pending = priv->tx->obj_num, + }; +const struct ethtool_coalesce ec = { + .rx_coalesce_usecs_irq = priv->rx_coalesce_usecs_irq, + .rx_max_coalesced_frames_irq = priv->rx_obj_num_coalesce_irq, + .tx_coalesce_usecs_irq = priv->tx_coalesce_usecs_irq, + .tx_max_coalesced_frames_irq = priv->tx_obj_num_coalesce_irq, + };struct can_ram_layout layout; -can_ram_get_layout (&layout, &mcp251xfd_ram_config,NULL ,NULL , fd_mode); - priv->rx_obj_num = layout.default_rx; - tx_ring->obj_num = layout.default_tx; +can_ram_get_layout (&layout, &mcp251xfd_ram_config, &ring, &ec, fd_mode); + + priv->rx_obj_num = layout.cur_rx; + priv->rx_obj_num_coalesce_irq = layout.rx_coalesce; + + tx_ring->obj_num = layout.cur_tx; + priv->tx_obj_num_coalesce_irq = layout.tx_coalesce; }if (fd_mode) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 155/375 rust: kbuild: fix export of bss symbols
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Hindborg <[email protected]>
[ Upstream commit b8673d56935c32a4e0a1a0b40951fdd313dbf340 ]
Symbols in the bss segment are not currently exported. This is a problem for Rust modules that link against statics, that are resident in the kernel image. Thus export symbols in the bss segment.
--- rust/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
rust/Makefile +1 -1
@@ -359,7 +359,7 @@ $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE quiet_cmd_exports = EXPORTS $@ cmd_exports = \ $(NM) -p --defined-only $< \ - | awk '/ (T|R|D) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ + | awk '/ (T|R|D|B) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(call if_changed,exports)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 156/375 cifs: Fix lack of credit renegotiation on read retry
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 6a5dcd487791e0c2d86622064602a5c7459941ed ]
When netfslib asks cifs to issue a read operation, it prefaces this with a call to ->clamp_length() which cifs uses to negotiate credits, providing receive capacity on the server; however, in the event that a read op needs reissuing, netfslib doesn't call ->clamp_length() again as that could shorten the subrequest, leaving a gap.
This causes the retried read to be done with zero credits which causes the server to reject it with STATUS_INVALID_PARAMETER. This is a problem for a DIO read that is requested that would go over the EOF. The short read will be retried, causing EINVAL to be returned to the user when it fails.
Fix this by making cifs_req_issue_read() negotiate new credits if retrying (NETFS_SREQ_RETRYING now gets set in the read side as well as the write side in this instance).
This isn't sufficient, however: the new credits might not be sufficient to complete the remainder of the read, so also add an additional field, rreq->actual_len, that holds the actual size of the op we want to perform without having to alter subreq->len.
We then rely on repeated short reads being retried until we finish the read or reach the end of file and make a zero-length read.
Also fix a couple of places where the subrequest start and length need to be altered by the amount so far transferred when being used.
--- fs/netfs/io.c | 2 ++ fs/smb/client/cifsglob.h | 1 + fs/smb/client/file.c | 37 +++++++++++++++++++++++++++++++++---- fs/smb/client/smb2ops.c | 2 +- fs/smb/client/smb2pdu.c | 28 +++++++++++++++++----------- fs/smb/client/trace.h | 1 + 6 files changed, 55 insertions(+), 16 deletions(-)
fs/netfs/io.c +2 -0
@@ -306,6 +306,7 @@ static bool netfs_rreq_perform_resubmissions(struct netfs_io_request *rreq)break ; subreq->source =NETFS_DOWNLOAD_FROM_SERVER ; subreq->error =0 ; +__set_bit (NETFS_SREQ_RETRYING , &subreq->flags);netfs_stat (&netfs_n_rh_download_instead);trace_netfs_sreq (subreq, netfs_sreq_trace_download_instead);netfs_get_subrequest (subreq, netfs_sreq_trace_get_resubmit);
@@ -313,6 +314,7 @@ static bool netfs_rreq_perform_resubmissions(struct netfs_io_request *rreq)netfs_reset_subreq_iter (rreq, subreq);netfs_read_from_server (rreq, subreq); }else if (test_bit (NETFS_SREQ_SHORT_IO , &subreq->flags)) { +__set_bit (NETFS_SREQ_RETRYING , &subreq->flags);netfs_reset_subreq_iter (rreq, subreq);netfs_rreq_short_read (rreq, subreq); }
fs/smb/client/cifsglob.h +1 -0
@@ -1508,6 +1508,7 @@ struct cifs_io_subrequest {struct cifs_io_request *req; };ssize_t got_bytes; +size_t actual_len;unsigned int xid;int result;bool have_xid;
fs/smb/client/file.c +33 -4
@@ -111,6 +111,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq) goto fail; } + wdata->actual_len = wdata->subreq.len; rc =adjust_credits (wdata->server, wdata, cifs_trace_rw_credits_issue_write_adjust);if (rc) goto fail;
@@ -153,7 +154,7 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq) struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq);struct TCP_Server_Info *server = req->server;struct cifs_sb_info *cifs_sb =CIFS_SB (rreq->inode->i_sb); -size_t rsize =0 ; +size_t rsize;int rc; rdata->xid =get_xid ();
@@ -166,8 +167,8 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq) cifs_sb->ctx); - rc = server->ops->wait_mtu_credits (server, cifs_sb->ctx->rsize, &rsize, - &rdata->credits); + rc = server->ops->wait_mtu_credits (server, cifs_sb->ctx->rsize, + &rsize, &rdata->credits);if (rc) { subreq->error = rc;return false;
@@ -183,7 +184,8 @@ static bool cifs_clamp_length(struct netfs_io_subrequest *subreq) server->credits, server->in_flight,0 , cifs_trace_rw_credits_read_submit); - subreq->len =min_t (size_t, subreq->len, rsize); + subreq->len =umin (subreq->len, rsize); + rdata->actual_len = subreq->len;#ifdef CONFIG_CIFS_SMB_DIRECT if (server->smbd_conn)
@@ -203,12 +205,39 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq)struct netfs_io_request *rreq = subreq->rreq; struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq); struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq); +struct TCP_Server_Info *server = req->server; +struct cifs_sb_info *cifs_sb =CIFS_SB (rreq->inode->i_sb);int rc =0 ;cifs_dbg (FYI ,"%s: op=%08x[%x] mapping=%p len=%zu/%zu\n" , __func__, rreq->debug_id, subreq->debug_index, rreq->mapping, subreq->transferred, subreq->len); +if (test_bit (NETFS_SREQ_RETRYING , &subreq->flags)) { +/* +* As we're issuing a retry, we need to negotiate some new +* credits otherwise the server may reject the op with +* INVALID_PARAMETER. Note, however, we may get back less +* credit than we need to complete the op, in which case, we +* shorten the op and rely on additional rounds of retry. +*/ +size_t rsize =umin (subreq->len - subreq->transferred, + cifs_sb->ctx->rsize); + + rc = server->ops->wait_mtu_credits (server, rsize, &rdata->actual_len, + &rdata->credits); +if (rc) + goto out; + + rdata->credits.in_flight_check =1 ; + +trace_smb3_rw_credits (rdata->rreq->debug_id, + rdata->subreq.debug_index, + rdata->credits.value, + server->credits, server->in_flight,0 , + cifs_trace_rw_credits_read_resubmit); + } +if (req->cfile->invalidHandle) { do { rc = cifs_reopen_file(req->cfile, true);
fs/smb/client/smb2ops.c +1 -1
@@ -301,7 +301,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, unsigned int /*enum smb3_rw_credits_trace*/ trace) {struct cifs_credits *credits = &subreq->credits; -int new_val =DIV_ROUND_UP (subreq->subreq.len,SMB2_MAX_BUFFER_SIZE ); +int new_val =DIV_ROUND_UP (subreq->actual_len,SMB2_MAX_BUFFER_SIZE );int scredits, in_flight;if (!credits->value || credits->value == new_val)
fs/smb/client/smb2pdu.c +17 -11
@@ -4523,9 +4523,9 @@ smb2_readv_callback(struct mid_q_entry *mid)"rdata server %p != mid server %p" , rdata->server, mid->server); -cifs_dbg (FYI ,"%s: mid=%llu state=%d result=%d bytes=%zu\n" , +cifs_dbg (FYI ,"%s: mid=%llu state=%d result=%d bytes=%zu/%zu\n" , __func__, mid->mid, mid->mid_state, rdata->result, - rdata->subreq.len); + rdata->actual_len, rdata->subreq.len - rdata->subreq.transferred);switch (mid->mid_state) {case MID_RESPONSE_RECEIVED :
@@ -4579,15 +4579,18 @@ smb2_readv_callback(struct mid_q_entry *mid) rdata->subreq.debug_index, rdata->xid, rdata->req->cfile->fid.persistent_fid, - tcon->tid, tcon->ses->Suid, rdata->subreq.start, - rdata->subreq.len, rdata->result); + tcon->tid, tcon->ses->Suid, + rdata->subreq.start + rdata->subreq.transferred, + rdata->actual_len, + rdata->result); }else trace_smb3_read_done (rdata->rreq->debug_id, rdata->subreq.debug_index, rdata->xid, rdata->req->cfile->fid.persistent_fid, tcon->tid, tcon->ses->Suid, - rdata->subreq.start, rdata->got_bytes); + rdata->subreq.start + rdata->subreq.transferred, + rdata->got_bytes);if (rdata->result == -ENODATA ) {/* We may have got an EOF error because fallocate
@@ -4615,6 +4618,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) {int rc, flags =0 ;char *buf; +struct netfs_io_subrequest *subreq = &rdata->subreq;struct smb2_hdr *shdr;struct cifs_io_parms io_parms;struct smb_rqst rqst = { .rq_iov = rdata->iov,
@@ -4625,15 +4629,15 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)int credit_request;cifs_dbg (FYI ,"%s: offset=%llu bytes=%zu\n" , - __func__, rdata->subreq.start, rdata->subreq.len); + __func__, subreq->start, subreq->len);if (!rdata->server) rdata->server =cifs_pick_channel (tcon->ses); io_parms.tcon =tlink_tcon (rdata->req->cfile->tlink); io_parms.server = server = rdata->server; - io_parms.offset = rdata->subreq.start; - io_parms.length = rdata->subreq.len; + io_parms.offset = subreq->start + subreq->transferred; + io_parms.length = rdata->actual_len; io_parms.persistent_fid = rdata->req->cfile->fid.persistent_fid; io_parms.volatile_fid = rdata->req->cfile->fid.volatile_fid; io_parms.pid = rdata->req->pid;
@@ -4648,11 +4652,13 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) rdata->iov[0 ].iov_base = buf; rdata->iov[0 ].iov_len = total_len; + rdata->got_bytes =0 ; + rdata->result =0 ; shdr = (struct smb2_hdr *)buf;if (rdata->credits.value >0 ) { - shdr->CreditCharge =cpu_to_le16 (DIV_ROUND_UP (rdata->subreq.len, + shdr->CreditCharge =cpu_to_le16 (DIV_ROUND_UP (rdata->actual_len,SMB2_MAX_BUFFER_SIZE )); credit_request =le16_to_cpu (shdr->CreditCharge) +8 ;if (server->credits >= server->max_credits)
@@ -4676,11 +4682,11 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)if (rc) {cifs_stats_fail_inc (io_parms.tcon,SMB2_READ_HE );trace_smb3_read_err (rdata->rreq->debug_id, - rdata->subreq.debug_index, + subreq->debug_index, rdata->xid, io_parms.persistent_fid, io_parms.tcon->tid, io_parms.tcon->ses->Suid, - io_parms.offset, io_parms.length, rc); + io_parms.offset, rdata->actual_len, rc); } async_readv_out:
fs/smb/client/trace.h +1 -0
@@ -30,6 +30,7 @@ EM(cifs_trace_rw_credits_old_session, "old-session") \ EM(cifs_trace_rw_credits_read_response_add, "rd-resp-add") \ EM(cifs_trace_rw_credits_read_response_clear, "rd-resp-clr") \ + EM(cifs_trace_rw_credits_read_resubmit, "rd-resubmit") \ EM(cifs_trace_rw_credits_read_submit, "rd-submit ") \ EM(cifs_trace_rw_credits_write_prepare, "wr-prepare ") \EM (cifs_trace_rw_credits_write_response_add,"wr-resp-add" ) \
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 157/375 netfs, cifs: Fix handling of short DIO read
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 1da29f2c39b67b846b74205c81bf0ccd96d34727 ]
Short DIO reads, particularly in relation to cifs, are not being handled correctly by cifs and netfslib. This can be tested by doing a DIO read of a file where the size of read is larger than the size of the file. When it crosses the EOF, it gets a short read and this gets retried, and in the case of cifs, the retry read fails, with the failure being translated to ENODATA.
Fix this by the following means:
(1) Add a flag, NETFS_SREQ_HIT_EOF, for the filesystem to set when it detects that the read did hit the EOF.
(2) Make the netfslib read assessment stop processing subrequests when it encounters one with that flag set.
(3) Return rreq->transferred, the accumulated contiguous amount read to that point, to userspace for a DIO read.
(4) Make cifs set the flag and clear the error if the read RPC returned ENODATA.
(5) Make cifs set the flag and clear the error if a short read occurred without error and the read-to file position is now at the remote inode size.
--- fs/netfs/io.c | 17 +++++++++++------ fs/smb/client/smb2pdu.c | 13 +++++++++---- include/linux/netfs.h | 1 + 3 files changed, 21 insertions(+), 10 deletions(-)
fs/netfs/io.c +11 -6
@@ -368,7 +368,8 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)if (subreq->error || subreq->transferred ==0 )break ; transferred += subreq->transferred; -if (subreq->transferred < subreq->len) +if (subreq->transferred < subreq->len || +test_bit (NETFS_SREQ_HIT_EOF , &subreq->flags))break ; }
@@ -503,7 +504,8 @@ void netfs_subreq_terminated(struct netfs_io_subrequest *subreq, subreq->error =0 ; subreq->transferred += transferred_or_error; -if (subreq->transferred < subreq->len) +if (subreq->transferred < subreq->len && + !test_bit (NETFS_SREQ_HIT_EOF , &subreq->flags)) goto incomplete; complete:
@@ -777,10 +779,13 @@ int netfs_begin_read(struct netfs_io_request *rreq, bool sync) TASK_UNINTERRUPTIBLE); ret = rreq->error; -if (ret ==0 && rreq->submitted < rreq->len && - rreq->origin !=NETFS_DIO_READ ) { -trace_netfs_failure (rreq,NULL , ret, netfs_fail_short_read); - ret = -EIO ; +if (ret ==0 ) { +if (rreq->origin ==NETFS_DIO_READ ) { + ret = rreq->transferred; + }else if (rreq->submitted < rreq->len) { +trace_netfs_failure (rreq,NULL , ret, netfs_fail_short_read); + ret = -EIO ; + } } }else {/* If we decrement nr_outstanding to 0, the ref belongs to us. */
fs/smb/client/smb2pdu.c +9 -4
@@ -4501,6 +4501,7 @@ static void smb2_readv_callback(struct mid_q_entry *mid) {struct cifs_io_subrequest *rdata = mid->callback_data; +struct netfs_inode *ictx =netfs_inode (rdata->rreq->inode);struct cifs_tcon *tcon =tlink_tcon (rdata->req->cfile->tlink);struct TCP_Server_Info *server = rdata->server; struct smb2_hdr *shdr =
@@ -4593,11 +4594,15 @@ smb2_readv_callback(struct mid_q_entry *mid) rdata->got_bytes);if (rdata->result == -ENODATA ) { -/* We may have got an EOF error because fallocate -* failed to enlarge the file. -*/ -if (rdata->subreq.start < rdata->subreq.rreq->i_size) +__set_bit (NETFS_SREQ_HIT_EOF , &rdata->subreq.flags); + rdata->result =0 ; + }else { +if (rdata->got_bytes < rdata->actual_len && + rdata->subreq.start + rdata->subreq.transferred + rdata->got_bytes == + ictx->remote_i_size) { +__set_bit (NETFS_SREQ_HIT_EOF , &rdata->subreq.flags); rdata->result =0 ; + } } trace_smb3_rw_credits(rreq_debug_id, subreq_debug_index, rdata->credits.value, server->credits, server->in_flight,
include/linux/netfs.h +1 -0
@@ -200,6 +200,7 @@ struct netfs_io_subrequest {#define NETFS_SREQ_NEED_RETRY 9/* Set if the filesystem requests a retry */ #define NETFS_SREQ_RETRYING 10/* Set if we're retrying */ #define NETFS_SREQ_FAILED 11/* Set if the subreq failed unretryably */ +#define NETFS_SREQ_HIT_EOF 12/* Set if we hit the EOF */ };enum netfs_io_origin {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 158/375 cifs: Fix copy offload to flush destination region
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 8101d6e112e2524e967368f920c404ae445a9757 ]
Fix cifs_file_copychunk_range() to flush the destination region before invalidating it to avoid potential loss of data should the copy fail, in whole or in part, in some way.
--- fs/smb/client/cifsfs.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-)
fs/smb/client/cifsfs.c +4 -17
@@ -1341,7 +1341,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,struct cifsFileInfo *smb_file_target;struct cifs_tcon *src_tcon;struct cifs_tcon *target_tcon; -unsigned long long destend, fstart, fend;ssize_t rc;cifs_dbg (FYI ,"copychunk range\n" );
@@ -1391,25 +1390,13 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, goto unlock; } - destend = destoff + len -1 ; - -/* Flush the folios at either end of the destination range to prevent -* accidental loss of dirty data outside of the range. +/* Flush and invalidate all the folios in the destination region. If +* the copy was successful, then some of the flush is extra overhead, +* but we need to allow for the copy failing in some way (eg. ENOSPC). */ - fstart = destoff; - fend = destend; - - rc =cifs_flush_folio (target_inode, destoff, &fstart, &fend, true); + rc =filemap_invalidate_inode (target_inode, true, destoff, destoff + len -1 );if (rc) goto unlock; - rc =cifs_flush_folio (target_inode, destend, &fstart, &fend, false); -if (rc) - goto unlock; -if (fend > target_cifsi->netfs.zero_point) - target_cifsi->netfs.zero_point = fend +1 ; - -/* Discard all the folios that overlap the destination region. */ -truncate_inode_pages_range (&target_inode->i_data, fstart, fend);fscache_invalidate (cifs_inode_cookie (target_inode),NULL ,i_size_read (target_inode),0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 159/375 cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 91d1dfae464987aaf6c79ff51d8674880fb3be77 ]
Under certain conditions, the range to be cleared by FALLOC_FL_ZERO_RANGE may only be buffered locally and not yet have been flushed to the server. For example:
xfs_io -f -t -c "pwrite -S 0x41 0 4k" \ -c "pwrite -S 0x42 4k 4k" \ -c "fzero 0 4k" \ -c "pread -v 0 8k" /xfstest.test/foo
will write two 4KiB blocks of data, which get buffered in the pagecache, and then fallocate() is used to clear the first 4KiB block on the server - but we don't flush the data first, which means the EOF position on the server is wrong, and so the FSCTL_SET_ZERO_DATA RPC fails (and xfs_io ignores the error), but then when we try to read it, we see the old data.
Fix this by preflushing any part of the target region that above the server's idea of the EOF position to force the server to update its EOF position.
Note, however, that we don't want to simply expand the file by moving the EOF before doing the FSCTL_SET_ZERO_DATA[*] because someone else might see the zeroed region or if the RPC fails we then have to try to clean it up or risk getting corruption.
[*] And we have to move the EOF first otherwise FSCTL_SET_ZERO_DATA won't do what we want.
This fixes the generic/008 xfstest.
[!] Note: A better way to do this might be to split the operation into two
parts: we only do FSCTL_SET_ZERO_DATA for the part of the range below the server's EOF and then, if that worked, invalidate the buffered pages for the part above the range.
--- fs/smb/client/smb2ops.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
fs/smb/client/smb2ops.c +14 -2
@@ -3219,13 +3219,15 @@ static long smb3_zero_data(struct file *file, struct cifs_tcon *tcon, }static long smb3_zero_range (struct file *file,struct cifs_tcon *tcon, -loff_t offset,loff_t len,bool keep_size) +unsigned long long offset,unsigned long long len, +bool keep_size) {struct cifs_ses *ses = tcon->ses;struct inode *inode =file_inode (file);struct cifsInodeInfo *cifsi =CIFS_I (inode);struct cifsFileInfo *cfile = file->private_data; -unsigned long long new_size; +struct netfs_inode *ictx =netfs_inode (inode); +unsigned long long i_size, new_size, remote_size;long rc;unsigned int xid;
@@ -3237,6 +3239,16 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,inode_lock (inode);filemap_invalidate_lock (inode->i_mapping); + i_size =i_size_read (inode); + remote_size = ictx->remote_i_size; +if (offset + len >= remote_size && offset < i_size) { +unsigned long long top =umin (offset + len, i_size); + + rc =filemap_write_and_wait_range (inode->i_mapping, offset, top -1 ); +if (rc <0 ) + goto zero_range_exit; + } +/* * We zero the range through ioctl, so we need remove the page caches * first, otherwise the data may be inconsistent with the server.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 160/375 igb: Fix not clearing TimeSync interrupts for 82580
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daiwei Li <[email protected]>
[ Upstream commit ba8cf80724dbc09825b52498e4efacb563935408 ]
82580 NICs have a hardware bug that makes it
necessary to write into the TSICR (TimeSync Interrupt Cause) register to clear it:
https://lore.kernel.org/all/CDCB8BE0.1EC2C%[email protected]/
Add a conditional so only for 82580 we write into the TSICR register, so we don't risk losing events for other models.
Without this change, when running ptp4l with an Intel 82580 card, I get the following output:
Quoted 3 lines
timed out while polling for tx timestamp increasing
tx_timestamp_timeoutor increasing kworker priority may correct this issue, but a driver bug likely causes it
This goes away with this change.
This (partially) reverts commit ee14cc9ea19b ("igb: Fix missing time sync events").
--- drivers/net/ethernet/intel/igb/igb_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/intel/igb/igb_main.c +10 -0
@@ -6961,10 +6961,20 @@ static void igb_extts(struct igb_adapter *adapter, int tsintr_tt)static void igb_tsync_interrupt (struct igb_adapter *adapter) { +const u32 mask = (TSINTR_SYS_WRAP |E1000_TSICR_TXTS | +TSINTR_TT0 |TSINTR_TT1 | +TSINTR_AUTT0 |TSINTR_AUTT1 );struct e1000_hw *hw = &adapter->hw;u32 tsicr =rd32 (E1000_TSICR );struct ptp_clock_event event; +if (hw->mac.type == e1000_82580) { +/* 82580 has a hardware bug that requires an explicit +* write to clear the TimeSync interrupt cause. +*/ +wr32 (E1000_TSICR , tsicr & mask); + } +if (tsicr &TSINTR_SYS_WRAP ) { event.type =PTP_CLOCK_PPS ;if (adapter->ptp_caps.pps)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 161/375 ice: Add netif_device_attach/detach into PF reset flow
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawid Osuchowski <[email protected]>
[ Upstream commit d11a67634227f9f9da51938af085fb41a733848f ]
Ethtool callbacks can be executed while reset is in progress and try to access deleted resources, e.g. getting coalesce settings can result in a NULL pointer dereference seen below.
Reproduction steps:
Once the driver is fully initialized, trigger reset:
# echo 1 > /sys/class/net/<interface>/device/reset when reset is in progress try to get coalesce settings using ethtool: # ethtool -c <interface>
BUG: kernel NULL pointer dereference, address: 0000000000000020 PGD 0 P4D 0 Oops: Oops: 0000 [#1] PREEMPT SMP PTI CPU: 11 PID: 19713 Comm: ethtool Tainted: G S 6.10.0-rc7+ #7 RIP: 0010:ice_get_q_coalesce+0x2e/0xa0 [ice] RSP: 0018:ffffbab1e9bcf6a8 EFLAGS: 00010206 RAX: 000000000000000c RBX: ffff94512305b028 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffff9451c3f2e588 RDI: ffff9451c3f2e588 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: ffff9451c3f2e580 R11: 000000000000001f R12: ffff945121fa9000 R13: ffffbab1e9bcf760 R14: 0000000000000013 R15: ffffffff9e65dd40 FS: 00007faee5fbe740(0000) GS:ffff94546fd80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000020 CR3: 0000000106c2e005 CR4: 00000000001706f0 Call Trace: <TASK> ice_get_coalesce+0x17/0x30 [ice] coalesce_prepare_data+0x61/0x80 ethnl_default_doit+0xde/0x340 genl_family_rcv_msg_doit+0xf2/0x150 genl_rcv_msg+0x1b3/0x2c0 netlink_rcv_skb+0x5b/0x110 genl_rcv+0x28/0x40 netlink_unicast+0x19c/0x290 netlink_sendmsg+0x222/0x490 __sys_sendto+0x1df/0x1f0 __x64_sys_sendto+0x24/0x30 do_syscall_64+0x82/0x160 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7faee60d8e27
Calling netif_device_detach() before reset makes the net core not call the driver when ethtool command is issued, the attempt to execute an ethtool command during reset will result in the following message:
netlink error: No such device
instead of NULL pointer dereference. Once reset is done and ice_rebuild() is executing, the netif_device_attach() is called to allow for ethtool operations to occur again in a safe manner.
--- drivers/net/ethernet/intel/ice/ice_main.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ethernet/intel/ice/ice_main.c +7 -0
@@ -609,6 +609,9 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)memset (&vsi->mqprio_qopt,0 ,sizeof (vsi->mqprio_qopt)); } } + +if (vsi->netdev) +netif_device_detach (vsi->netdev); skip:/* clear SW filtering DB */
@@ -7590,6 +7593,7 @@ static void ice_update_pf_netdev_link(struct ice_pf *pf)*/ static void ice_rebuild (struct ice_pf *pf,enum ice_reset_req reset_type) { +struct ice_vsi *vsi =ice_get_main_vsi (pf);struct device *dev =ice_pf_to_dev (pf);struct ice_hw *hw = &pf->hw;bool dvm;
@@ -7734,6 +7738,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)ice_rebuild_arfs (pf); } +if (vsi && vsi->netdev) +netif_device_attach (vsi->netdev); +ice_update_pf_netdev_link (pf);/* tell the firmware we are up */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 162/375 platform/x86: dell-smbios: Fix error path in dell_smbios_init()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Mishin <[email protected]>
[ Upstream commit ffc17e1479e8e9459b7afa80e5d9d40d0dd78abb ]
In case of error in build_tokens_sysfs(), all the memory that has been allocated is freed at end of this function. But then free_group() is called which performs memory deallocation again.
Also, instead of free_group() call, there should be exit_dell_smbios_smm() and exit_dell_smbios_wmi() calls, since there is initialization, but there is no release of resources in case of an error.
Fix these issues by replacing free_group() call with exit_dell_smbios_wmi() and exit_dell_smbios_smm().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/platform/x86/dell/dell-smbios-base.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/platform/x86/dell/dell-smbios-base.c +4 -1
@@ -587,7 +587,10 @@ static int __init dell_smbios_init(void)return 0 ; fail_sysfs: -free_group (platform_device); +if (!wmi) +exit_dell_smbios_wmi (); +if (!smm) +exit_dell_smbios_smm (); fail_create_group:platform_device_del (platform_device);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 163/375 spi: intel: Add check devm_kasprintf() returned value
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Han <[email protected]>
[ Upstream commit 2920294686ec23211637998f3ec386dfd3d784a6 ]
intel_spi_populate_chip() use devm_kasprintf() to set pdata->name. This can return a NULL pointer on failure but this returned value is not checked.
--- drivers/spi/spi-intel.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/spi/spi-intel.c +3 -0
@@ -1390,6 +1390,9 @@ static int intel_spi_populate_chip(struct intel_spi *ispi) pdata->name =devm_kasprintf (ispi->dev,GFP_KERNEL ,"%s-chip1" ,dev_name (ispi->dev)); +if (!pdata->name) +return -ENOMEM ; + pdata->nr_parts =1 ; parts =devm_kcalloc (ispi->dev, pdata->nr_parts,sizeof (*parts),GFP_KERNEL );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 164/375 regulator: core: Stub devm_regulator_bulk_get_const() if !CONFIG_REGULATOR
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit 1a5caec7f80ca2e659c03f45378ee26915f4eda2 ]
When adding devm_regulator_bulk_get_const() I missed adding a stub for when CONFIG_REGULATOR is not enabled. Under certain conditions (like randconfig testing) this can cause the compiler to reports errors like:
error: implicit declaration of function 'devm_regulator_bulk_get_const'; did you mean 'devm_regulator_bulk_get_enable'?
Add the stub.
--- include/linux/regulator/consumer.h | 8 ++++++++ 1 file changed, 8 insertions(+)
include/linux/regulator/consumer.h +8 -0
@@ -451,6 +451,14 @@ static inline int of_regulator_bulk_get_all(struct device *dev, struct device_noreturn 0 ; } +static inline int devm_regulator_bulk_get_const ( +struct device *dev,int num_consumers, +const struct regulator_bulk_data *in_consumers, +struct regulator_bulk_data **out_consumers) +{ +return 0 ; +} +static inline int regulator_bulk_enable (int num_consumers,struct regulator_bulk_data *consumers) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 165/375 can: kvaser_pciefd: Skip redundant NULL pointer check in ISR
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Jocic <[email protected]>
[ Upstream commit ac765219c2c4e44f29063724c8d36435a3e61985 ]
This check is already done at the creation of the net devices in kvaser_pciefd_setup_can_ctrls called from kvaser_pciefd_probe.
If it fails, the driver won't load, so there should be no need to repeat the check inside the ISR. The number of channels is read from the FPGA and should be trusted.
Stable-dep-of: dd885d90c047 ("can: kvaser_pciefd: Use a single write when releasing RX buffers")
--- drivers/net/can/kvaser_pciefd.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/net/can/kvaser_pciefd.c +0 -6
@@ -1701,12 +1701,6 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)kvaser_pciefd_receive_irq (pcie);for (i =0 ; i < pcie->nr_channels; i++) { -if (!pcie->can[i]) { -dev_err (&pcie->pci->dev, -"IRQ mask points to unallocated controller\n" ); -break ; - } -/* Check that mask matches channel (i) IRQ mask */ if (board_irq & irq_mask->kcan_tx[i])kvaser_pciefd_transmit_irq (pcie->can[i]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 166/375 can: kvaser_pciefd: Remove unnecessary comment
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Jocic <[email protected]>
[ Upstream commit 11d186697ceb10b68c6a1fd505635346b1ccd055 ]
The code speaks for itself.
Stable-dep-of: dd885d90c047 ("can: kvaser_pciefd: Use a single write when releasing RX buffers")
--- drivers/net/can/kvaser_pciefd.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/can/kvaser_pciefd.c +0 -1
@@ -1701,7 +1701,6 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)kvaser_pciefd_receive_irq (pcie);for (i =0 ; i < pcie->nr_channels; i++) { -/* Check that mask matches channel (i) IRQ mask */ if (board_irq & irq_mask->kcan_tx[i])kvaser_pciefd_transmit_irq (pcie->can[i]); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 167/375 can: kvaser_pciefd: Rename board_irq to pci_irq
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Jocic <[email protected]>
[ Upstream commit cbf88a6ba7bb6ce0d3131b119298f73bd7b18459 ]
Rename the variable name board_irq in the ISR to pci_irq to be more specific and to match the macro by which it is read.
Stable-dep-of: dd885d90c047 ("can: kvaser_pciefd: Use a single write when releasing RX buffers")
--- drivers/net/can/kvaser_pciefd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/can/kvaser_pciefd.c +4 -4
@@ -1691,17 +1691,17 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev) {struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask; -u32 board_irq =ioread32 (KVASER_PCIEFD_PCI_IRQ_ADDR (pcie)); +u32 pci_irq =ioread32 (KVASER_PCIEFD_PCI_IRQ_ADDR (pcie));int i; -if (!(board_irq & irq_mask->all)) +if (!(pci_irq & irq_mask->all))return IRQ_NONE ; -if (board_irq & irq_mask->kcan_rx0) +if (pci_irq & irq_mask->kcan_rx0)kvaser_pciefd_receive_irq (pcie);for (i =0 ; i < pcie->nr_channels; i++) { -if (board_irq & irq_mask->kcan_tx[i]) +if (pci_irq & irq_mask->kcan_tx[i])kvaser_pciefd_transmit_irq (pcie->can[i]); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 168/375 can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Jocic <[email protected]>
[ Upstream commit 48f827d4f48f5243e37b9240029ce3f456d1f490 ]
A new interrupt is triggered by resetting the DMA RX buffers. Since MSI interrupts are faster than legacy interrupts, the reset of the DMA buffers must be moved to the very end of the ISR, otherwise a new MSI interrupt will be masked by the current one.
Stable-dep-of: dd885d90c047 ("can: kvaser_pciefd: Use a single write when releasing RX buffers")
--- drivers/net/can/kvaser_pciefd.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
drivers/net/can/kvaser_pciefd.c +18 -12
@@ -1640,23 +1640,15 @@ static int kvaser_pciefd_read_buffer(struct kvaser_pciefd *pcie, int dma_buf)return res; } -static void kvaser_pciefd_receive_irq (struct kvaser_pciefd *pcie) +static u32 kvaser_pciefd_receive_irq (struct kvaser_pciefd *pcie) {u32 irq =ioread32 (KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IRQ_REG ); -if (irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) { +if (irq &KVASER_PCIEFD_SRB_IRQ_DPD0 )kvaser_pciefd_read_buffer (pcie,0 ); -/* Reset DMA buffer 0 */ -iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB0 , -KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); - } -if (irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) { +if (irq &KVASER_PCIEFD_SRB_IRQ_DPD1 )kvaser_pciefd_read_buffer (pcie,1 ); -/* Reset DMA buffer 1 */ -iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB1 , -KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); - } if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 || irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
@@ -1665,6 +1657,7 @@ static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)dev_err (&pcie->pci->dev,"DMA IRQ error 0x%08X\n" , irq);iowrite32 (irq,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_IRQ_REG ); +return irq; }static void kvaser_pciefd_transmit_irq (struct kvaser_pciefd_can *can)
@@ -1692,19 +1685,32 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;u32 pci_irq =ioread32 (KVASER_PCIEFD_PCI_IRQ_ADDR (pcie)); +u32 srb_irq =0 ;int i;if (!(pci_irq & irq_mask->all))return IRQ_NONE ;if (pci_irq & irq_mask->kcan_rx0) -kvaser_pciefd_receive_irq (pcie); + srb_irq =kvaser_pciefd_receive_irq (pcie);for (i =0 ; i < pcie->nr_channels; i++) {if (pci_irq & irq_mask->kcan_tx[i])kvaser_pciefd_transmit_irq (pcie->can[i]); } +if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) { +/* Reset DMA buffer 0, may trigger new interrupt */ +iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB0 , +KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); + } + +if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) { +/* Reset DMA buffer 1, may trigger new interrupt */ +iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB1 , +KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); + } +return IRQ_HANDLED ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 169/375 can: kvaser_pciefd: Use a single write when releasing RX buffers
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Jocic <[email protected]>
[ Upstream commit dd885d90c047dbdd2773c1d33954cbd8747d81e2 ]
Kvaser's PCIe cards uses the KCAN FPGA IP block which has dual 4K buffers for incoming messages shared by all (currently up to eight) channels. While the driver processes messages in one buffer, new incoming messages are stored in the other and so on.
The design of KCAN is such that a buffer must be fully read and then released. Releasing a buffer will make the FPGA switch buffers. If the other buffer contains at least one incoming message the FPGA will also instantly issue a new interrupt, if not the interrupt will be issued after receiving the first new message.
With IRQx interrupts, it takes a little time for the interrupt to happen, enough for any previous ISR call to do it's business and return, but MSI interrupts are way faster so this time is reduced to almost nothing.
So with MSI, releasing the buffer HAS to be the very last action of the ISR before returning, otherwise the new interrupt might be "masked" by the kernel because the previous ISR call hasn't returned. And the interrupts are edge-triggered so we cannot loose one, or the ping-pong reading process will stop.
This is why this patch modifies the driver to use a single write to the SRB_CMD register before returning.
--- drivers/net/can/kvaser_pciefd.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
drivers/net/can/kvaser_pciefd.c +8 -10
@@ -1686,6 +1686,7 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;u32 pci_irq =ioread32 (KVASER_PCIEFD_PCI_IRQ_ADDR (pcie));u32 srb_irq =0 ; +u32 srb_release =0 ;int i;if (!(pci_irq & irq_mask->all))
@@ -1699,17 +1700,14 @@ static irqreturn_t kvaser_pciefd_irq_handler(int irq, void *dev)kvaser_pciefd_transmit_irq (pcie->can[i]); } -if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) { -/* Reset DMA buffer 0, may trigger new interrupt */ -iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB0 , -KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); - } +if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD0 ) + srb_release |=KVASER_PCIEFD_SRB_CMD_RDB0 ; -if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) { -/* Reset DMA buffer 1, may trigger new interrupt */ -iowrite32 (KVASER_PCIEFD_SRB_CMD_RDB1 , -KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG ); - } +if (srb_irq &KVASER_PCIEFD_SRB_IRQ_DPD1 ) + srb_release |=KVASER_PCIEFD_SRB_CMD_RDB1 ; + +if (srb_release) +iowrite32 (srb_release,KVASER_PCIEFD_SRB_ADDR (pcie) +KVASER_PCIEFD_SRB_CMD_REG );return IRQ_HANDLED ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 170/375 Bluetooth: qca: If memdump doesnt work, re-enable IBS
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit 8ae22de9d2eae3c432de64bf2b3a5a69cf1d1124 ]
On systems in the field, we are seeing this sometimes in the kernel logs:
Bluetooth: qca_controller_memdump() hci0: hci_devcd_init Return:-95
This means that _something_ decided that it wanted to get a memdump but then hci_devcd_init() returned -EOPNOTSUPP (AKA -95).
The cleanup code in qca_controller_memdump() when we get back an error from hci_devcd_init() undoes most things but forgets to clear QCA_IBS_DISABLED. One side effect of this is that, during the next suspend, qca_suspend() will always get a timeout.
Let's fix it so that we clear the bit.
--- drivers/bluetooth/hci_qca.c | 1 + 1 file changed, 1 insertion(+)
drivers/bluetooth/hci_qca.c +1 -0
@@ -1090,6 +1090,7 @@ static void qca_controller_memdump(struct work_struct *work) qca->memdump_state =QCA_MEMDUMP_COLLECTED ;cancel_delayed_work (&qca->ctrl_memdump_timeout);clear_bit (QCA_MEMDUMP_COLLECTION , &qca->flags); +clear_bit (QCA_IBS_DISABLED , &qca->flags);mutex_unlock (&qca->hci_memdump_lock);return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 171/375 Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit c898f6d7b093bd71e66569cd6797c87d4056f44b ]
This introduces hci_cmd_sync_run/hci_cmd_sync_run_once which acts like hci_cmd_sync_queue/hci_cmd_sync_queue_once but runs immediately when already on hdev->cmd_sync_work context.
Stable-dep-of: 227a0cdf4a02 ("Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT")
--- include/net/bluetooth/hci_sync.h | 4 +++ net/bluetooth/hci_sync.c | 42 ++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-)
include/net/bluetooth/hci_sync.h +4 -0
@@ -52,6 +52,10 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy);int hci_cmd_sync_queue_once (struct hci_dev *hdev,hci_cmd_sync_work_func_t func,void *data,hci_cmd_sync_work_destroy_t destroy); +int hci_cmd_sync_run (struct hci_dev *hdev,hci_cmd_sync_work_func_t func, +void *data,hci_cmd_sync_work_destroy_t destroy); +int hci_cmd_sync_run_once (struct hci_dev *hdev,hci_cmd_sync_work_func_t func, +void *data,hci_cmd_sync_work_destroy_t destroy);struct hci_cmd_sync_work_entry *hci_cmd_sync_lookup_entry (struct hci_dev *hdev,hci_cmd_sync_work_func_t func,void *data,hci_cmd_sync_work_destroy_t destroy);
net/bluetooth/hci_sync.c +40 -2
60 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 172/375 Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 227a0cdf4a028a73dc256d0f5144b4808d718893 ]
MGMT_OP_DISCONNECT can be called while mgmt_device_connected has not been called yet, which will cause the connection procedure to be aborted, so mgmt_device_disconnected shall still respond with command complete to MGMT_OP_DISCONNECT and just not emit MGMT_EV_DEVICE_DISCONNECTED since MGMT_EV_DEVICE_CONNECTED was never sent.
To fix this MGMT_OP_DISCONNECT is changed to work similarly to other command which do use hci_cmd_sync_queue and then use hci_conn_abort to disconnect and returns the result, in order for hci_conn_abort to be used from hci_cmd_sync context it now uses hci_cmd_sync_run_once.
--- net/bluetooth/hci_conn.c | 6 ++- net/bluetooth/mgmt.c | 84 ++++++++++++++++++++-------------------- 2 files changed, 47 insertions(+), 43 deletions(-)
net/bluetooth/hci_conn.c +5 -1
@@ -2953,5 +2953,9 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)return 0 ; } -return hci_cmd_sync_queue_once (hdev, abort_conn_sync, conn,NULL ); +/* Run immediately if on cmd_sync_work since this may be called +* as a result to MGMT_OP_DISCONNECT/MGMT_OP_UNPAIR which does +* already queue its callback on cmd_sync_work. +*/ +return hci_cmd_sync_run_once (hdev, abort_conn_sync, conn,NULL ); }
net/bluetooth/mgmt.c +42 -42
133 lines not on this page · raw message
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 173/375 hwmon: ltc2991: fix register bits defines
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit 6a422a96bc84cf9b9f0ff741f293a1f9059e0883 ]
In the LTC2991, V5 and V6 channels use the low nibble of the "V5, V6, V7, and V8 Control Register" for configuration, but currently, the high nibble is defined.
This patch changes the defines to use the low nibble.
Message-ID: <[email protected]>
--- drivers/hwmon/ltc2991.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/hwmon/ltc2991.c +3 -3
@@ -42,9 +42,9 @@#define LTC2991_V7_V8_FILT_EN BIT(7)#define LTC2991_V7_V8_TEMP_EN BIT(5)#define LTC2991_V7_V8_DIFF_EN BIT(4) -#define LTC2991_V5_V6_FILT_EN BIT(7) -#define LTC2991_V5_V6_TEMP_EN BIT(5) -#define LTC2991_V5_V6_DIFF_EN BIT(4) +#define LTC2991_V5_V6_FILT_EN BIT(3) +#define LTC2991_V5_V6_TEMP_EN BIT(1) +#define LTC2991_V5_V6_DIFF_EN BIT(0)#define LTC2991_REPEAT_ACQ_EN BIT(4)#define LTC2991_T_INT_FILT_EN BIT(3)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 174/375 scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <[email protected]>
[ Upstream commit a3f6a89c834a4cba0f881da21307b26de3796133 ]
Richard reports that since 772dd0342727c ("mm: enumerate all gfp flags"), gfp-translate is broken, as the bit numbers are implicit, leaving the shell script unable to extract them. Even more, some bits are now at a variable location, making it double extra hard to parse using a simple shell script.
Use a brute-force approach to the problem by generating a small C stub that will use the enum to dump the interesting bits.
As an added bonus, we are now able to identify invalid bits for a given configuration. As an added drawback, we cannot parse include files that predate this change anymore. Tough luck.
--- scripts/gfp-translate | 66 ++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 17 deletions(-)
scripts/gfp-translate +49 -17
@@ -62,25 +62,57 @@ if [ "$GFPMASK" = "none" ]; then fi # Extract GFP flags from the kernel source -TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 -grep -q ___GFP $SOURCE/include/linux/gfp_types.h -if [ $? -eq 0 ]; then - grep "^#define ___GFP" $SOURCE/include/linux/gfp_types.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE -else - grep "^#define __GFP" $SOURCE/include/linux/gfp_types.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE -fi +TMPFILE=`mktemp -t gfptranslate-XXXXXX.c` || exit 1 -# Parse the flags -IFS=" -" echo Source: $SOURCE echo Parsing: $GFPMASK -for LINE in `cat $TMPFILE`; do - MASK=`echo $LINE | awk '{print $3}'` - if [ $(($GFPMASK&$MASK)) -ne 0 ]; then - echo $LINE - fi -done -rm -f $TMPFILE +( + cat <<EOF +#include <stdint.h> +#include <stdio.h> + +// Try to fool compiler.h into not including extra stuff +#define __ASSEMBLY__ 1 + +#include <generated/autoconf.h> +#include <linux/gfp_types.h> + +static const char *masks[] = { +EOF + + sed -nEe 's/^[[:space:]]+(___GFP_.*)_BIT,.*$/\1/p' $SOURCE/include/linux/gfp_types.h | + while read b; do + cat <<EOF +#if defined($b) && ($b > 0) + [${b}_BIT] = "$b", +#endif +EOF + done + + cat <<EOF +}; + +int main(int argc, char *argv[]) +{ + unsigned long long mask = $GFPMASK; + + for (int i = 0; i < sizeof(mask) * 8; i++) { + unsigned long long bit = 1ULL << i; + if (mask & bit) + printf("\t%-25s0x%llx\n", + (i < ___GFP_LAST_BIT && masks[i]) ? + masks[i] : "*** INVALID ***", + bit); + } + + return 0; +} +EOF +) > $TMPFILE + +${CC:-gcc} -Wall -o ${TMPFILE}.bin -I $SOURCE/include $TMPFILE && ${TMPFILE}.bin + +rm -f $TMPFILE ${TMPFILE}.bin + exit 0
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 175/375 igc: Unlock on error in igc_io_resume()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit ef4a99a0164e3972abb421cbb1b09ea6c61414df ]
Call rtnl_unlock() on this error path, before returning.
--- drivers/net/ethernet/intel/igc/igc_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/igc/igc_main.c +1 -0
@@ -7417,6 +7417,7 @@ static void igc_io_resume(struct pci_dev *pdev)rtnl_lock ();if (netif_running (netdev)) {if (igc_open (netdev)) { +rtnl_unlock ();netdev_err (netdev,"igc_open failed after reset\n" );return ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 176/375 hwmon: (hp-wmi-sensors) Check if WMI event data exists
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit a54da9df75cd1b4b5028f6c60f9a211532680585 ]
The BIOS can choose to return no event data in response to a WMI event, so the ACPI object passed to the WMI notify handler can be NULL.
Check for such a situation and ignore the event in such a case.
Message-ID: <[email protected]>
--- drivers/hwmon/hp-wmi-sensors.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/hwmon/hp-wmi-sensors.c +2 -0
@@ -1637,6 +1637,8 @@ static void hp_wmi_notify(u32 value, void *context) goto out_unlock; wobj = out.pointer; +if (!wobj) + goto out_unlock; err =populate_event_from_wobj (dev, &event, wobj);if (err) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 177/375 perf lock contention: Fix spinlock and rwlock accounting
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
[ Upstream commit 287bd5cf06e0f2c02293ce942777ad1f18059ed3 ]
The spinlock and rwlock use a single-element per-cpu array to track current locks due to performance reason. But this means the key is always available and it cannot simply account lock stats in the array because some of them are invalid.
In fact, the contention_end() program in the BPF invalidates the entry by setting the 'lock' value to 0 instead of deleting the entry for the hashmap. So it should skip entries with the lock value of 0 in the account_end_timestamp().
Otherwise, it'd have spurious high contention on an idle machine:
$ sudo perf lock con -ab -Y spinlock sleep 3 contended total wait max wait avg wait type caller
8 4.72 s 1.84 s 590.46 ms spinlock rcu_core+0xc7
8 1.87 s 1.87 s 233.48 ms spinlock process_one_work+0x1b5
2 1.87 s 1.87 s 933.92 ms spinlock worker_thread+0x1a2
3 1.81 s 1.81 s 603.93 ms spinlock tmigr_update_events+0x13c
2 1.72 s 1.72 s 861.98 ms spinlock tick_do_update_jiffies64+0x25
6 42.48 us 13.02 us 7.08 us spinlock futex_q_lock+0x2a
1 13.03 us 13.03 us 13.03 us spinlock futex_wake+0xce
1 11.61 us 11.61 us 11.61 us spinlock rcu_core+0xc7I don't believe it has contention on a spinlock longer than 1 second. After this change, it only reports some small contentions.
$ sudo perf lock con -ab -Y spinlock sleep 3 contended total wait max wait avg wait type caller
4 133.51 us 43.29 us 33.38 us spinlock tick_do_update_jiffies64+0x25
4 69.06 us 31.82 us 17.27 us spinlock process_one_work+0x1b5
2 50.66 us 25.77 us 25.33 us spinlock rcu_core+0xc7
1 28.45 us 28.45 us 28.45 us spinlock rcu_core+0xc7
1 24.77 us 24.77 us 24.77 us spinlock tmigr_update_events+0x13c
1 23.34 us 23.34 us 23.34 us spinlock raw_spin_rq_lock_nested+0x15--- tools/perf/util/bpf_lock_contention.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/bpf_lock_contention.c +3 -0
@@ -286,6 +286,9 @@ static void account_end_timestamp(struct lock_contention *con) goto next;for (int i =0 ; i < total_cpus; i++) { +if (cpu_data[i].lock ==0 ) +continue ; +update_lock_stat (stat_fd,-1 , end_ts, aggr_mode, &cpu_data[i]); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 178/375 net: ethernet: ti: am65-cpsw: Fix RX statistics for XDP_TX and XDP_REDIRECT
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros <[email protected]>
[ Upstream commit 624d3291484f9cada10660f820db926c0bce7741 ]
We are not using ndev->stats for rx_packets and rx_bytes anymore. Instead, we use per CPU stats which are collated in am65_cpsw_nuss_ndo_get_stats().
Fix RX statistics for XDP_TX and XDP_REDIRECT cases.
--- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/net/ethernet/ti/am65-cpsw-nuss.c +13 -4
@@ -998,7 +998,9 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_common *common, int desc_idx, int cpu, int *len) { struct am65_cpsw_rx_chn *rx_chn = &common->rx_chns; +struct am65_cpsw_ndev_priv *ndev_priv;struct net_device *ndev = port->ndev; +struct am65_cpsw_ndev_stats *stats;int ret =AM65_CPSW_XDP_CONSUMED ;struct am65_cpsw_tx_chn *tx_chn;struct netdev_queue *netif_txq;
@@ -1016,6 +1018,9 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_common *common,/* XDP prog might have changed packet data and boundaries */ *len = xdp->data_end - xdp->data; + ndev_priv =netdev_priv (ndev); + stats =this_cpu_ptr (ndev_priv->stats); +switch (act) {case XDP_PASS : ret =AM65_CPSW_XDP_PASS ;
@@ -1035,16 +1040,20 @@ static int am65_cpsw_run_xdp(struct am65_cpsw_common *common,if (err) goto drop; - ndev->stats.rx_bytes += *len; - ndev->stats.rx_packets++; +u64_stats_update_begin (&stats->syncp); + stats->rx_bytes += *len; + stats->rx_packets++; +u64_stats_update_end (&stats->syncp); ret =AM65_CPSW_XDP_CONSUMED ; goto out;case XDP_REDIRECT :if (unlikely (xdp_do_redirect (ndev, xdp, prog))) goto drop; - ndev->stats.rx_bytes += *len; - ndev->stats.rx_packets++; +u64_stats_update_begin (&stats->syncp); + stats->rx_bytes += *len; + stats->rx_packets++; +u64_stats_update_end (&stats->syncp); ret =AM65_CPSW_XDP_REDIRECT ; goto out;default :
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 179/375 net: phy: Fix missing of_node_put() for leds
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 2560db6ede1aaf162a73b2df43e0b6c5ed8819f7 ]
The call of of_get_child_by_name() will cause refcount incremented for leds, if it succeeds, it should call of_node_put() to decrease it, fix it.
--- drivers/net/phy/phy_device.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/phy/phy_device.c +2 -0
@@ -3346,11 +3346,13 @@ static int of_phy_leds(struct phy_device *phydev) err =of_phy_led (phydev, led);if (err) {of_node_put (led); +of_node_put (leds);phy_leds_unregister (phydev);return err; } } +of_node_put (leds);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 180/375 ptp: ocp: convert serial ports to array
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vadim Fedorenko <[email protected]>
[ Upstream commit d7875b4b078f7e2d862e88aed99c3ea0381aa189 ]
Simplify serial port management code by using array of ports and helpers to get the name of the port. This change is needed to make the next patch simplier.
Stable-dep-of: 82ace0c8fe9b ("ptp: ocp: adjust sysfs entries to expose tty information")
--- drivers/ptp/ptp_ocp.c | 120 ++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 63 deletions(-)
drivers/ptp/ptp_ocp.c +57 -63
@@ -316,6 +316,15 @@ struct ptp_ocp_serial_port {#define OCP_SERIAL_LEN 6#define OCP_SMA_NUM 4 +enum { +PORT_GNSS , +PORT_GNSS2 , +PORT_MAC ,/* miniature atomic clock */ +PORT_NMEA , + + __PORT_COUNT, +}; +struct ptp_ocp {struct pci_dev *pdev;struct device dev;
@@ -357,10 +366,7 @@ struct ptp_ocp {struct delayed_work sync_work;int id;int n_irqs; -struct ptp_ocp_serial_port gnss_port; -struct ptp_ocp_serial_port gnss2_port; -struct ptp_ocp_serial_port mac_port;/* miniature atomic clock */ -struct ptp_ocp_serial_port nmea_port; +struct ptp_ocp_serial_port port[__PORT_COUNT];bool fw_loader;u8 fw_tag;u16 fw_version;
@@ -655,28 +661,28 @@ static struct ocp_resource ocp_fb_resource[] = { }, }, { - OCP_SERIAL_RESOURCE(gnss_port), + OCP_SERIAL_RESOURCE(port[PORT_GNSS]), .offset = 0x00160000 + 0x1000, .irq_vec = 3, .extra = &(struct ptp_ocp_serial_port ) { .baud =115200 , }, }, { -OCP_SERIAL_RESOURCE (gnss2_port), +OCP_SERIAL_RESOURCE (port[PORT_GNSS2 ]), .offset = 0x00170000 + 0x1000, .irq_vec = 4, .extra = &(struct ptp_ocp_serial_port) { .baud =115200 , }, }, { -OCP_SERIAL_RESOURCE (mac_port), +OCP_SERIAL_RESOURCE (port[PORT_MAC ]), .offset = 0x00180000 + 0x1000, .irq_vec = 5, .extra = &(struct ptp_ocp_serial_port) { .baud =57600 , }, }, { -OCP_SERIAL_RESOURCE (nmea_port), +OCP_SERIAL_RESOURCE (port[PORT_NMEA ]), .offset = 0x00190000 + 0x1000, .irq_vec = 10, }, {
@@ -740,7 +746,7 @@ static struct ocp_resource ocp_art_resource[] = { .offset = 0x01000000, .size = 0x10000, }, { - OCP_SERIAL_RESOURCE(gnss_port), + OCP_SERIAL_RESOURCE(port[PORT_GNSS]), .offset = 0x00160000 + 0x1000, .irq_vec = 3, .extra = &(struct ptp_ocp_serial_port ) { .baud =115200 ,
@@ -839,7 +845,7 @@ static struct ocp_resource ocp_art_resource[] = { }, }, { - OCP_SERIAL_RESOURCE(mac_port), + OCP_SERIAL_RESOURCE(port[PORT_MAC]), .offset = 0x00190000, .irq_vec = 7, .extra = &(struct ptp_ocp_serial_port ) { .baud =9600 ,
@@ -950,14 +956,14 @@ static struct ocp_resource ocp_adva_resource[] = { .offset = 0x00220000, .size = 0x1000, }, { - OCP_SERIAL_RESOURCE(gnss_port), + OCP_SERIAL_RESOURCE(port[PORT_GNSS]), .offset = 0x00160000 + 0x1000, .irq_vec = 3, .extra = &(struct ptp_ocp_serial_port ) { .baud =9600 , }, }, { -OCP_SERIAL_RESOURCE (mac_port), +OCP_SERIAL_RESOURCE (port[PORT_MAC ]), .offset = 0x00180000 + 0x1000, .irq_vec = 5, .extra = &(struct ptp_ocp_serial_port) { .baud =115200 ,
@@ -1649,6 +1655,15 @@ ptp_ocp_tod_gnss_name(int idx)return gnss_name[idx]; } +static const char * +ptp_ocp_tty_port_name (int idx) +{ +static const char *const tty_name[] = { +"GNSS" ,"GNSS2" ,"MAC" ,"NMEA" + }; +return tty_name[idx]; +} +struct ptp_ocp_nvmem_match_info {struct ptp_ocp *bp;const void *const tag;
@@ -3960,16 +3975,11 @@ ptp_ocp_summary_show(struct seq_file *s, void *data) bp =dev_get_drvdata (dev);seq_printf (s,"%7s: /dev/ptp%d\n" ,"PTP" ,ptp_clock_index (bp->ptp)); -if (bp->gnss_port.line !=-1 ) -seq_printf (s,"%7s: /dev/ttyS%d\n" ,"GNSS1" , - bp->gnss_port.line); -if (bp->gnss2_port.line !=-1 ) -seq_printf (s,"%7s: /dev/ttyS%d\n" ,"GNSS2" , - bp->gnss2_port.line); -if (bp->mac_port.line !=-1 ) -seq_printf (s,"%7s: /dev/ttyS%d\n" ,"MAC" , bp->mac_port.line); -if (bp->nmea_port.line !=-1 ) -seq_printf (s,"%7s: /dev/ttyS%d\n" ,"NMEA" , bp->nmea_port.line); +for (i =0 ; i < __PORT_COUNT; i++) { +if (bp->port[i].line !=-1 ) +seq_printf (s,"%7s: /dev/ttyS%d\n" ,ptp_ocp_tty_port_name (i), + bp->port[i].line); + }memset (sma_val,0xff ,sizeof (sma_val));if (bp->sma_map1) {
@@ -4279,7 +4289,7 @@ ptp_ocp_dev_release(struct device *dev)static int ptp_ocp_device_init (struct ptp_ocp *bp,struct pci_dev *pdev) { -int err; +int i, err;mutex_lock (&ptp_ocp_lock); err =idr_alloc (&ptp_ocp_idr, bp,0 ,0 ,GFP_KERNEL );
@@ -4292,10 +4302,10 @@ ptp_ocp_device_init(struct ptp_ocp *bp, struct pci_dev *pdev) bp->ptp_info = ptp_ocp_clock_info;spin_lock_init (&bp->lock); - bp->gnss_port.line =-1 ; - bp->gnss2_port.line =-1 ; - bp->mac_port.line =-1 ; - bp->nmea_port.line =-1 ; + +for (i =0 ; i < __PORT_COUNT; i++) + bp->port[i].line =-1 ; + bp->pdev = pdev;device_initialize (&bp->dev);
@@ -4351,23 +4361,15 @@ ptp_ocp_complete(struct ptp_ocp *bp) {struct pps_device *pps;char buf[32 ]; +int i; -if (bp->gnss_port.line !=-1 ) { -sprintf (buf,"ttyS%d" , bp->gnss_port.line); -ptp_ocp_link_child (bp, buf,"ttyGNSS" ); - } -if (bp->gnss2_port.line !=-1 ) { -sprintf (buf,"ttyS%d" , bp->gnss2_port.line); -ptp_ocp_link_child (bp, buf,"ttyGNSS2" ); - } -if (bp->mac_port.line !=-1 ) { -sprintf (buf,"ttyS%d" , bp->mac_port.line); -ptp_ocp_link_child (bp, buf,"ttyMAC" ); - } -if (bp->nmea_port.line !=-1 ) { -sprintf (buf,"ttyS%d" , bp->nmea_port.line); -ptp_ocp_link_child (bp, buf,"ttyNMEA" ); +for (i =0 ; i < __PORT_COUNT; i++) { +if (bp->port[i].line !=-1 ) { +sprintf (buf,"ttyS%d" , bp->port[i].line); +ptp_ocp_link_child (bp, buf,ptp_ocp_tty_port_name (i)); + } } +sprintf (buf,"ptp%d" ,ptp_clock_index (bp->ptp));ptp_ocp_link_child (bp, buf,"ptp" );
@@ -4416,23 +4418,20 @@ ptp_ocp_info(struct ptp_ocp *bp) };struct device *dev = &bp->pdev->dev;u32 reg; +int i;ptp_ocp_phc_info (bp); -ptp_ocp_serial_info (dev,"GNSS" , bp->gnss_port.line, - bp->gnss_port.baud); -ptp_ocp_serial_info (dev,"GNSS2" , bp->gnss2_port.line, - bp->gnss2_port.baud); -ptp_ocp_serial_info (dev,"MAC" , bp->mac_port.line, bp->mac_port.baud); -if (bp->nmea_out && bp->nmea_port.line !=-1 ) { - bp->nmea_port.baud =-1 ; +for (i =0 ; i < __PORT_COUNT; i++) { +if (i ==PORT_NMEA && bp->nmea_out && bp->port[PORT_NMEA ].line !=-1 ) { + bp->port[PORT_NMEA ].baud =-1 ; - reg =ioread32 (&bp->nmea_out->uart_baud); -if (reg <ARRAY_SIZE (nmea_baud)) - bp->nmea_port.baud = nmea_baud[reg]; - -ptp_ocp_serial_info (dev,"NMEA" , bp->nmea_port.line, - bp->nmea_port.baud); + reg =ioread32 (&bp->nmea_out->uart_baud); +if (reg <ARRAY_SIZE (nmea_baud)) + bp->port[PORT_NMEA ].baud = nmea_baud[reg]; + } +ptp_ocp_serial_info (dev,ptp_ocp_tty_port_name (i), bp->port[i].line, + bp->port[i].baud); } }
@@ -4473,14 +4472,9 @@ ptp_ocp_detach(struct ptp_ocp *bp)for (i =0 ; i <4 ; i++)if (bp->signal_out[i])ptp_ocp_unregister_ext (bp->signal_out[i]); -if (bp->gnss_port.line !=-1 ) -serial8250_unregister_port (bp->gnss_port.line); -if (bp->gnss2_port.line !=-1 ) -serial8250_unregister_port (bp->gnss2_port.line); -if (bp->mac_port.line !=-1 ) -serial8250_unregister_port (bp->mac_port.line); -if (bp->nmea_port.line !=-1 ) -serial8250_unregister_port (bp->nmea_port.line); +for (i =0 ; i < __PORT_COUNT; i++) +if (bp->port[i].line !=-1 ) +serial8250_unregister_port (bp->port[i].line);platform_device_unregister (bp->spi_flash);platform_device_unregister (bp->i2c_ctrl);if (bp->i2c_clk)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 181/375 ptp: ocp: adjust sysfs entries to expose tty information
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vadim Fedorenko <[email protected]>
[ Upstream commit 82ace0c8fe9b025eaa273365e27057402cdaeb02 ]
Implement additional attribute group to expose serial port information. Fixes tag points to the commit which introduced the change in serial port subsystem and made it impossible to use symlinks.
--- drivers/ptp/ptp_ocp.c | 62 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-)
drivers/ptp/ptp_ocp.c +51 -11
@@ -3361,6 +3361,54 @@ static EXT_ATTR_RO(freq, frequency, 1); static EXT_ATTR_RO(freq, frequency, 2); static EXT_ATTR_RO(freq, frequency, 3); +static ssize_t +ptp_ocp_tty_show (struct device *dev,struct device_attribute *attr,char *buf) +{ +struct dev_ext_attribute *ea =to_ext_attr (attr); +struct ptp_ocp *bp =dev_get_drvdata (dev); + +return sysfs_emit (buf,"ttyS%d" , bp->port[(uintptr_t )ea->var].line); +} + +static umode_t +ptp_ocp_timecard_tty_is_visible (struct kobject *kobj,struct attribute *attr,int n) +{ +struct ptp_ocp *bp =dev_get_drvdata (kobj_to_dev (kobj)); +struct ptp_ocp_serial_port *port; +struct device_attribute *dattr; +struct dev_ext_attribute *ea; + +if (strncmp (attr->name,"tty" ,3 )) +return attr->mode; + + dattr = container_of(attr, struct device_attribute, attr); + ea = container_of(dattr, struct dev_ext_attribute, attr); + port = &bp->port[(uintptr_t )ea->var]; +return port->line ==-1 ?0 :0444 ; +} + +#define EXT_TTY_ATTR_RO (_name, _val) \ + struct dev_ext_attribute dev_attr_tty##_name = \ + { __ATTR(tty##_name, 0444, ptp_ocp_tty_show, NULL), (void *)_val } + +static EXT_TTY_ATTR_RO(GNSS, PORT_GNSS); +static EXT_TTY_ATTR_RO(GNSS2, PORT_GNSS2); +static EXT_TTY_ATTR_RO(MAC, PORT_MAC); +static EXT_TTY_ATTR_RO(NMEA, PORT_NMEA); +static struct attribute *ptp_ocp_timecard_tty_attrs[] = { + &dev_attr_ttyGNSS.attr.attr, + &dev_attr_ttyGNSS2.attr.attr, + &dev_attr_ttyMAC.attr.attr, + &dev_attr_ttyNMEA.attr.attr, +NULL , +}; + +static const struct attribute_group ptp_ocp_timecard_tty_group = { + .name ="tty" , + .attrs = ptp_ocp_timecard_tty_attrs, + .is_visible = ptp_ocp_timecard_tty_is_visible, +}; +static ssize_t serialnum_show (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -3790,6 +3838,7 @@ static const struct attribute_group fb_timecard_group = {static const struct ocp_attr_group fb_timecard_groups[] = { { .cap =OCP_CAP_BASIC , .group = &fb_timecard_group }, + { .cap =OCP_CAP_BASIC , .group = &ptp_ocp_timecard_tty_group }, { .cap =OCP_CAP_SIGNAL , .group = &fb_timecard_signal0_group }, { .cap =OCP_CAP_SIGNAL , .group = &fb_timecard_signal1_group }, { .cap =OCP_CAP_SIGNAL , .group = &fb_timecard_signal2_group },
@@ -3829,6 +3878,7 @@ static const struct attribute_group art_timecard_group = {static const struct ocp_attr_group art_timecard_groups[] = { { .cap =OCP_CAP_BASIC , .group = &art_timecard_group }, + { .cap =OCP_CAP_BASIC , .group = &ptp_ocp_timecard_tty_group }, { }, };
@@ -3856,6 +3906,7 @@ static const struct attribute_group adva_timecard_group = {static const struct ocp_attr_group adva_timecard_groups[] = { { .cap =OCP_CAP_BASIC , .group = &adva_timecard_group }, + { .cap =OCP_CAP_BASIC , .group = &ptp_ocp_timecard_tty_group }, { .cap =OCP_CAP_SIGNAL , .group = &fb_timecard_signal0_group }, { .cap =OCP_CAP_SIGNAL , .group = &fb_timecard_signal1_group }, { .cap =OCP_CAP_FREQ , .group = &fb_timecard_freq0_group },
@@ -4361,14 +4412,6 @@ ptp_ocp_complete(struct ptp_ocp *bp) {struct pps_device *pps;char buf[32 ]; -int i; - -for (i =0 ; i < __PORT_COUNT; i++) { -if (bp->port[i].line !=-1 ) { -sprintf (buf,"ttyS%d" , bp->port[i].line); -ptp_ocp_link_child (bp, buf,ptp_ocp_tty_port_name (i)); - } - }sprintf (buf,"ptp%d" ,ptp_clock_index (bp->ptp));ptp_ocp_link_child (bp, buf,"ptp" );
@@ -4440,9 +4483,6 @@ ptp_ocp_detach_sysfs(struct ptp_ocp *bp) {struct device *dev = &bp->dev; -sysfs_remove_link (&dev->kobj,"ttyGNSS" ); -sysfs_remove_link (&dev->kobj,"ttyGNSS2" ); -sysfs_remove_link (&dev->kobj,"ttyMAC" );sysfs_remove_link (&dev->kobj,"ptp" );sysfs_remove_link (&dev->kobj,"pps" ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 182/375 ice: move netif_queue_set_napi to rtnl-protected sections
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 2a5dc090b92cfa5270e20056074241c6db5c9cdd ]
Currently, netif_queue_set_napi() is called from ice_vsi_rebuild() that is not rtnl-locked when called from the reset. This creates the need to take the rtnl_lock just for a single function and complicates the synchronization with .ndo_bpf. At the same time, there no actual need to fill napi-to-queue information at this exact point.
Fill napi-to-queue information when opening the VSI and clear it when the VSI is being closed. Those routines are already rtnl-locked.
Also, rewrite napi-to-queue assignment in a way that prevents inclusion of XDP queues, as this leads to out-of-bounds writes, such as one below.
[ +0.000004] BUG: KASAN: slab-out-of-bounds in netif_queue_set_napi+0x1c2/0x1e0 [ +0.000012] Write of size 8 at addr ffff889881727c80 by task bash/7047 [ +0.000006] CPU: 24 PID: 7047 Comm: bash Not tainted 6.10.0-rc2+ #2 [ +0.000004] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0014.082620210524 08/26/2021 [ +0.000003] Call Trace: [ +0.000003] <TASK> [ +0.000002] dump_stack_lvl+0x60/0x80 [ +0.000007] print_report+0xce/0x630 [ +0.000007] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ +0.000007] ? __virt_addr_valid+0x1c9/0x2c0 [ +0.000005] ? netif_queue_set_napi+0x1c2/0x1e0 [ +0.000003] kasan_report+0xe9/0x120 [ +0.000004] ? netif_queue_set_napi+0x1c2/0x1e0 [ +0.000004] netif_queue_set_napi+0x1c2/0x1e0 [ +0.000005] ice_vsi_close+0x161/0x670 [ice] [ +0.000114] ice_dis_vsi+0x22f/0x270 [ice] [ +0.000095] ice_pf_dis_all_vsi.constprop.0+0xae/0x1c0 [ice] [ +0.000086] ice_prepare_for_reset+0x299/0x750 [ice] [ +0.000087] pci_dev_save_and_disable+0x82/0xd0 [ +0.000006] pci_reset_function+0x12d/0x230 [ +0.000004] reset_store+0xa0/0x100 [ +0.000006] ? __pfx_reset_store+0x10/0x10 [ +0.000002] ? __pfx_mutex_lock+0x10/0x10 [ +0.000004] ? __check_object_size+0x4c1/0x640 [ +0.000007] kernfs_fop_write_iter+0x30b/0x4a0 [ +0.000006] vfs_write+0x5d6/0xdf0 [ +0.000005] ? fd_install+0x180/0x350 [ +0.000005] ? __pfx_vfs_write+0x10/0xA10 [ +0.000004] ? do_fcntl+0x52c/0xcd0 [ +0.000004] ? kasan_save_track+0x13/0x60 [ +0.000003] ? kasan_save_free_info+0x37/0x60 [ +0.000006] ksys_write+0xfa/0x1d0 [ +0.000003] ? __pfx_ksys_write+0x10/0x10 [ +0.000002] ? __x64_sys_fcntl+0x121/0x180 [ +0.000004] ? _raw_spin_lock+0x87/0xe0 [ +0.000005] do_syscall_64+0x80/0x170 [ +0.000007] ? _raw_spin_lock+0x87/0xe0 [ +0.000004] ? __pfx__raw_spin_lock+0x10/0x10 [ +0.000003] ? file_close_fd_locked+0x167/0x230 [ +0.000005] ? syscall_exit_to_user_mode+0x7d/0x220 [ +0.000005] ? do_syscall_64+0x8c/0x170 [ +0.000004] ? do_syscall_64+0x8c/0x170 [ +0.000003] ? do_syscall_64+0x8c/0x170 [ +0.000003] ? fput+0x1a/0x2c0 [ +0.000004] ? filp_close+0x19/0x30 [ +0.000004] ? do_dup2+0x25a/0x4c0 [ +0.000004] ? __x64_sys_dup2+0x6e/0x2e0 [ +0.000002] ? syscall_exit_to_user_mode+0x7d/0x220 [ +0.000004] ? do_syscall_64+0x8c/0x170 [ +0.000003] ? __count_memcg_events+0x113/0x380 [ +0.000005] ? handle_mm_fault+0x136/0x820 [ +0.000005] ? do_user_addr_fault+0x444/0xa80 [ +0.000004] ? clear_bhb_loop+0x25/0x80 [ +0.000004] ? clear_bhb_loop+0x25/0x80 [ +0.000002] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ +0.000005] RIP: 0033:0x7f2033593154
--- drivers/net/ethernet/intel/ice/ice_base.c | 11 +- drivers/net/ethernet/intel/ice/ice_lib.c | 129 ++++++---------------- drivers/net/ethernet/intel/ice/ice_lib.h | 10 +- drivers/net/ethernet/intel/ice/ice_main.c | 17 ++- 4 files changed, 49 insertions(+), 118 deletions(-)
drivers/net/ethernet/intel/ice/ice_base.c +3 -8
@@ -190,16 +190,11 @@ static void ice_free_q_vector(struct ice_vsi *vsi, int v_idx) } q_vector = vsi->q_vectors[v_idx]; -ice_for_each_tx_ring (tx_ring, q_vector->tx) { -ice_queue_set_napi (vsi, tx_ring->q_index,NETDEV_QUEUE_TYPE_TX , -NULL ); +ice_for_each_tx_ring (tx_ring, vsi->q_vectors[v_idx]->tx) tx_ring->q_vector =NULL ; - } -ice_for_each_rx_ring (rx_ring, q_vector->rx) { -ice_queue_set_napi (vsi, rx_ring->q_index,NETDEV_QUEUE_TYPE_RX , -NULL ); + +ice_for_each_rx_ring (rx_ring, vsi->q_vectors[v_idx]->rx) rx_ring->q_vector =NULL ; - }/* only VSI with an associated netdev is set up with NAPI */ if (vsi->netdev)
drivers/net/ethernet/intel/ice/ice_lib.c +31 -98
166 lines not on this page · raw message
drivers/net/ethernet/intel/ice/ice_lib.h +2 -8
@@ -44,16 +44,10 @@ void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc);struct ice_vsi *ice_vsi_setup (struct ice_pf *pf,struct ice_vsi_cfg_params *params); -void -ice_queue_set_napi (struct ice_vsi *vsi,unsigned int queue_index, -enum netdev_queue_type type,struct napi_struct *napi); - -void __ice_q_vector_set_napi_queues (struct ice_q_vector *q_vector,bool locked); - -void ice_q_vector_set_napi_queues (struct ice_q_vector *q_vector); -void ice_vsi_set_napi_queues (struct ice_vsi *vsi); +void ice_vsi_clear_napi_queues (struct ice_vsi *vsi); +int ice_vsi_release (struct ice_vsi *vsi);void ice_vsi_close (struct ice_vsi *vsi);
drivers/net/ethernet/intel/ice/ice_main.c +13 -4
@@ -3559,11 +3559,9 @@ static void ice_napi_add(struct ice_vsi *vsi)if (!vsi->netdev)return ; -ice_for_each_q_vector (vsi, v_idx) { +ice_for_each_q_vector (vsi, v_idx)netif_napi_add (vsi->netdev, &vsi->q_vectors[v_idx]->napi, ice_napi_poll); -__ice_q_vector_set_napi_queues (vsi->q_vectors[v_idx], false); - } }/**
@@ -5541,7 +5539,9 @@ static int ice_reinit_interrupt_scheme(struct ice_pf *pf)if (ret) goto err_reinit;ice_vsi_map_rings_to_vectors (pf->vsi[v]); +rtnl_lock ();ice_vsi_set_napi_queues (pf->vsi[v]); +rtnl_unlock (); } ret =ice_req_irq_msix_misc (pf);
@@ -5555,8 +5555,12 @@ static int ice_reinit_interrupt_scheme(struct ice_pf *pf) err_reinit:while (v--) -if (pf->vsi[v]) +if (pf->vsi[v]) { +rtnl_lock (); +ice_vsi_clear_napi_queues (pf->vsi[v]); +rtnl_unlock ();ice_vsi_free_q_vectors (pf->vsi[v]); + }return ret; }
@@ -5621,6 +5625,9 @@ static int ice_suspend(struct device *dev)ice_for_each_vsi (pf, v) {if (!pf->vsi[v])continue ; +rtnl_lock (); +ice_vsi_clear_napi_queues (pf->vsi[v]); +rtnl_unlock ();ice_vsi_free_q_vectors (pf->vsi[v]); }ice_clear_interrupt_scheme (pf);
@@ -7456,6 +7463,8 @@ int ice_vsi_open(struct ice_vsi *vsi) err =netif_set_real_num_rx_queues (vsi->netdev, vsi->num_rxq);if (err) goto err_set_qs; + +ice_vsi_set_napi_queues (vsi); } err =ice_up_complete (vsi);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 183/375 ice: protect XDP configuration with a mutex
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 2504b8405768a57a71e660dbfd5abd59f679a03f ]
The main threat to data consistency in ice_xdp() is a possible asynchronous PF reset. It can be triggered by a user or by TX timeout handler.
XDP setup and PF reset code access the same resources in the following sections:
* ice_vsi_close() in ice_prepare_for_reset() - already rtnl-locked
* ice_vsi_rebuild() for the PF VSI - not protected
* ice_vsi_open() - already rtnl-locked
With an unfortunate timing, such accesses can result in a crash such as the one below:
[ +1.999878] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 14
[ +2.002992] ice 0000:b1:00.0: Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring 18
[Mar15 18:17] ice 0000:b1:00.0 ens801f0np0: NETDEV WATCHDOG: CPU: 38: transmit queue 14 timed out 80692736 ms [ +0.000093] ice 0000:b1:00.0 ens801f0np0: tx_timeout: VSI_num: 6, Q 14, NTC: 0x0, HW_HEAD: 0x0, NTU: 0x0, INT: 0x4000001 [ +0.000012] ice 0000:b1:00.0 ens801f0np0: tx_timeout recovery level 1, txqueue 14
[ +0.394718] ice 0000:b1:00.0: PTP reset successful
[ +0.006184] BUG: kernel NULL pointer dereference, address: 0000000000000098
[ +0.000045] #PF: supervisor read access in kernel mode
[ +0.000023] #PF: error_code(0x0000) - not-present page
[ +0.000023] PGD 0 P4D 0
[ +0.000018] Oops: 0000 [#1] PREEMPT SMP NOPTI
[ +0.000023] CPU: 38 PID: 7540 Comm: kworker/38:1 Not tainted 6.8.0-rc7 #1
[ +0.000031] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0014.082620210524 08/26/2021 [ +0.000036] Workqueue: ice ice_service_task [ice]
[ +0.000183] RIP: 0010:ice_clean_tx_ring+0xa/0xd0 [ice]
[...]
[ +0.000013] Call Trace:
[ +0.000016] <TASK>
[ +0.000014] ? __die+0x1f/0x70
[ +0.000029] ? page_fault_oops+0x171/0x4f0
[ +0.000029] ? schedule+0x3b/0xd0
[ +0.000027] ? exc_page_fault+0x7b/0x180
[ +0.000022] ? asm_exc_page_fault+0x22/0x30
[ +0.000031] ? ice_clean_tx_ring+0xa/0xd0 [ice]
[ +0.000194] ice_free_tx_ring+0xe/0x60 [ice]
[ +0.000186] ice_destroy_xdp_rings+0x157/0x310 [ice]
[ +0.000151] ice_vsi_decfg+0x53/0xe0 [ice]
[ +0.000180] ice_vsi_rebuild+0x239/0x540 [ice]
[ +0.000186] ice_vsi_rebuild_by_type+0x76/0x180 [ice]
[ +0.000145] ice_rebuild+0x18c/0x840 [ice]
[ +0.000145] ? delay_tsc+0x4a/0xc0
[ +0.000022] ? delay_tsc+0x92/0xc0
[ +0.000020] ice_do_reset+0x140/0x180 [ice]
[ +0.000886] ice_service_task+0x404/0x1030 [ice]
[ +0.000824] process_one_work+0x171/0x340
[ +0.000685] worker_thread+0x277/0x3a0
[ +0.000675] ? preempt_count_add+0x6a/0xa0
[ +0.000677] ? _raw_spin_lock_irqsave+0x23/0x50
[ +0.000679] ? __pfx_worker_thread+0x10/0x10
[ +0.000653] kthread+0xf0/0x120
[ +0.000635] ? __pfx_kthread+0x10/0x10
[ +0.000616] ret_from_fork+0x2d/0x50
[ +0.000612] ? __pfx_kthread+0x10/0x10
[ +0.000604] ret_from_fork_asm+0x1b/0x30
[ +0.000604] </TASK>
The previous way of handling this through returning -EBUSY is not viable, particularly when destroying AF_XDP socket, because the kernel proceeds with removal anyway.
There is plenty of code between those calls and there is no need to create a large critical section that covers all of them, same as there is no need to protect ice_vsi_rebuild() with rtnl_lock().
Add xdp_state_lock mutex to protect ice_vsi_rebuild() and ice_xdp().
Leaving unprotected sections in between would result in two states that have to be considered:
1. when the VSI is closed, but not yet rebuild
2. when VSI is already rebuild, but not yet open
The latter case is actually already handled through !netif_running() case, we just need to adjust flag checking a little. The former one is not as trivial, because between ice_vsi_close() and ice_vsi_rebuild(), a lot of hardware interaction happens, this can make adding/deleting rings exit with an error. Luckily, VSI rebuild is pending and can apply new configuration for us in a managed fashion.
Therefore, add an additional VSI state flag ICE_VSI_REBUILD_PENDING to indicate that ice_xdp() can just hot-swap the program.
Also, as ice_vsi_rebuild() flow is touched in this patch, make it more consistent by deconfiguring VSI when coalesce allocation fails.
--- drivers/net/ethernet/intel/ice/ice.h | 2 ++ drivers/net/ethernet/intel/ice/ice_lib.c | 34 ++++++++++++++--------- drivers/net/ethernet/intel/ice/ice_main.c | 19 +++++++++---- drivers/net/ethernet/intel/ice/ice_xsk.c | 3 +- 4 files changed, 39 insertions(+), 19 deletions(-)
drivers/net/ethernet/intel/ice/ice.h +2 -0
@@ -318,6 +318,7 @@ enum ice_vsi_state {ICE_VSI_UMAC_FLTR_CHANGED ,ICE_VSI_MMAC_FLTR_CHANGED ,ICE_VSI_PROMISC_CHANGED , +ICE_VSI_REBUILD_PENDING , ICE_VSI_STATE_NBITS /* must be last */ };
@@ -411,6 +412,7 @@ struct ice_vsi {struct ice_tx_ring **xdp_rings;/* XDP ring array */ u16 num_xdp_txq;/* Used XDP queues */ u8 xdp_mapping_mode;/* ICE_MAP_MODE_[CONTIG|SCATTER] */ +struct mutex xdp_state_lock;struct net_device **target_netdevs;
drivers/net/ethernet/intel/ice/ice_lib.c +21 -13
@@ -447,6 +447,7 @@ static void ice_vsi_free(struct ice_vsi *vsi)ice_vsi_free_stats (vsi);ice_vsi_free_arrays (vsi); +mutex_destroy (&vsi->xdp_state_lock);mutex_unlock (&pf->sw_mutex);devm_kfree (dev, vsi); }
@@ -626,6 +627,8 @@ static struct ice_vsi *ice_vsi_alloc(struct ice_pf *pf) pf->next_vsi =ice_get_free_slot (pf->vsi, pf->num_alloc_vsi, pf->next_vsi); +mutex_init (&vsi->xdp_state_lock); + unlock_pf:mutex_unlock (&pf->sw_mutex);return vsi;
@@ -2972,19 +2975,23 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)if (WARN_ON (vsi->type ==ICE_VSI_VF && !vsi->vf))return -EINVAL ; +mutex_lock (&vsi->xdp_state_lock); + ret =ice_vsi_realloc_stat_arrays (vsi);if (ret) - goto err_vsi_cfg; + goto unlock;ice_vsi_decfg (vsi); ret =ice_vsi_cfg_def (vsi);if (ret) - goto err_vsi_cfg; + goto unlock; coalesce =kcalloc (vsi->num_q_vectors,sizeof (struct ice_coalesce_stored ),GFP_KERNEL ); -if (!coalesce) -return -ENOMEM ; +if (!coalesce) { + ret = -ENOMEM ; + goto decfg; + } prev_num_q_vectors =ice_vsi_rebuild_get_coalesce (vsi, coalesce);
@@ -2992,22 +2999,23 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)if (ret) {if (vsi_flags &ICE_VSI_FLAG_INIT ) { ret = -EIO ; - goto err_vsi_cfg_tc_lan; + goto free_coalesce; } -kfree (coalesce); -return ice_schedule_reset (pf,ICE_RESET_PFR ); + ret =ice_schedule_reset (pf,ICE_RESET_PFR ); + goto free_coalesce; }ice_vsi_rebuild_set_coalesce (vsi, coalesce, prev_num_q_vectors); -kfree (coalesce); +clear_bit (ICE_VSI_REBUILD_PENDING , vsi->state); -return 0 ; - -err_vsi_cfg_tc_lan: -ice_vsi_decfg (vsi); +free_coalesce:kfree (coalesce); -err_vsi_cfg: +decfg: +if (ret) +ice_vsi_decfg (vsi); +unlock: +mutex_unlock (&vsi->xdp_state_lock);return ret; }
drivers/net/ethernet/intel/ice/ice_main.c +14 -5
@@ -617,6 +617,7 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)/* clear SW filtering DB */ ice_clear_hw_tbls (hw);/* disable the VSIs and their queues that are not already DOWN */ +set_bit (ICE_VSI_REBUILD_PENDING ,ice_get_main_vsi (pf)->state);ice_pf_dis_all_vsi (pf, false);if (test_bit (ICE_FLAG_PTP_SUPPORTED , pf->flags))
@@ -3017,7 +3018,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, }/* hot swap progs and avoid toggling link */ -if (ice_is_xdp_ena_vsi (vsi) == !!prog) { +if (ice_is_xdp_ena_vsi (vsi) == !!prog || +test_bit (ICE_VSI_REBUILD_PENDING , vsi->state)) {ice_vsi_assign_bpf_prog (vsi, prog);return 0 ; }
@@ -3089,21 +3091,28 @@ static int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp) {struct ice_netdev_priv *np =netdev_priv (dev);struct ice_vsi *vsi = np->vsi; +int ret;if (vsi->type !=ICE_VSI_PF ) {NL_SET_ERR_MSG_MOD (xdp->extack,"XDP can be loaded only on PF VSI" );return -EINVAL ; } +mutex_lock (&vsi->xdp_state_lock); +switch (xdp->command) {case XDP_SETUP_PROG : -return ice_xdp_setup_prog (vsi, xdp->prog, xdp->extack); + ret =ice_xdp_setup_prog (vsi, xdp->prog, xdp->extack); +break ;case XDP_SETUP_XSK_POOL : -return ice_xsk_pool_setup (vsi, xdp->xsk.pool, - xdp->xsk.queue_id); + ret =ice_xsk_pool_setup (vsi, xdp->xsk.pool, xdp->xsk.queue_id); +break ;default : -return -EINVAL ; + ret = -EINVAL ; } + +mutex_unlock (&vsi->xdp_state_lock); +return ret; }/**
drivers/net/ethernet/intel/ice/ice_xsk.c +2 -1
@@ -390,7 +390,8 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) goto failure; } - if_running =netif_running (vsi->netdev) &&ice_is_xdp_ena_vsi (vsi); + if_running = !test_bit (ICE_VSI_DOWN , vsi->state) && +ice_is_xdp_ena_vsi (vsi);if (if_running) {struct ice_rx_ring *rx_ring = vsi->rx_rings[qid];
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 184/375 ice: check ICE_VSI_DOWN under rtnl_lock when preparing for reset
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit d8c40b9d3a6cef61eb5a0c58c34a3090ea938d89 ]
Consider the following scenario:
.ndo_bpf() | ice_prepare_for_reset() |
________________________|_______________________________________|rtnl_lock() | |ice_down() | |
| test_bit(ICE_VSI_DOWN) - true | | ice_dis_vsi() returns | ice_up() | | | proceeds to rebuild a running VSI |
.ndo_bpf() is not the only rtnl-locked callback that toggles the interface to apply new configuration. Another example is .set_channels().
To avoid the race condition above, act only after reading ICE_VSI_DOWN under rtnl_lock.
--- drivers/net/ethernet/intel/ice/ice_lib.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/ethernet/intel/ice/ice_lib.c +6 -6
@@ -2672,8 +2672,7 @@ int ice_ena_vsi(struct ice_vsi *vsi, bool locked)*/ void ice_dis_vsi (struct ice_vsi *vsi,bool locked) { -if (test_bit (ICE_VSI_DOWN , vsi->state)) -return ; +bool already_down =test_bit (ICE_VSI_DOWN , vsi->state);set_bit (ICE_VSI_NEEDS_RESTART , vsi->state);
@@ -2681,15 +2680,16 @@ void ice_dis_vsi(struct ice_vsi *vsi, bool locked)if (netif_running (vsi->netdev)) {if (!locked)rtnl_lock (); - -ice_vsi_close (vsi); + already_down =test_bit (ICE_VSI_DOWN , vsi->state); +if (!already_down) +ice_vsi_close (vsi);if (!locked)rtnl_unlock (); - }else { + }else if (!already_down) {ice_vsi_close (vsi); } - }else if (vsi->type ==ICE_VSI_CTRL ) { + }else if (vsi->type ==ICE_VSI_CTRL && !already_down) {ice_vsi_close (vsi); } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 185/375 ice: remove ICE_CFG_BUSY locking from AF_XDP code
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 7e3b407ccbea3259b8583ccc34807622025e390f ]
Locking used in ice_qp_ena() and ice_qp_dis() does pretty much nothing, because ICE_CFG_BUSY is a state flag that is supposed to be set in a PF state, not VSI one. Therefore it does not protect the queue pair from e.g. reset.
Remove ICE_CFG_BUSY locking from ice_qp_dis() and ice_qp_ena().
--- drivers/net/ethernet/intel/ice/ice_xsk.c | 9 --------- 1 file changed, 9 deletions(-)
drivers/net/ethernet/intel/ice/ice_xsk.c +0 -9
@@ -165,7 +165,6 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx)struct ice_q_vector *q_vector;struct ice_tx_ring *tx_ring;struct ice_rx_ring *rx_ring; -int timeout =50 ;int fail =0 ;int err;
@@ -176,13 +175,6 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) rx_ring = vsi->rx_rings[q_idx]; q_vector = rx_ring->q_vector; -while (test_and_set_bit (ICE_CFG_BUSY , vsi->state)) { - timeout--; -if (!timeout) -return -EBUSY ; -usleep_range (1000 ,2000 ); - } -synchronize_net ();netif_carrier_off (vsi->netdev);netif_tx_stop_queue (netdev_get_tx_queue (vsi->netdev, q_idx));
@@ -261,7 +253,6 @@ static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)netif_tx_start_queue (netdev_get_tx_queue (vsi->netdev, q_idx));netif_carrier_on (vsi->netdev); } -clear_bit (ICE_CFG_BUSY , vsi->state);return fail; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 186/375 ice: do not bring the VSI up, if it was down before the XDP setup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larysa Zaremba <[email protected]>
[ Upstream commit 04c7e14e5b0b6227e7b00d7a96ca2f2426ab9171 ]
After XDP configuration is completed, we bring the interface up unconditionally, regardless of its state before the call to .ndo_bpf().
Preserve the information whether the interface had to be brought down and later bring it up only in such case.
--- drivers/net/ethernet/intel/ice/ice_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/ice/ice_main.c +5 -2
@@ -3006,8 +3006,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, struct netlink_ext_ack *extack) {unsigned int frame_size = vsi->netdev->mtu +ICE_ETH_PKT_HDR_PAD ; -bool if_running =netif_running (vsi->netdev);int ret =0 , xdp_ring_err =0 ; +bool if_running;if (prog && !prog->aux->xdp_has_frags) {if (frame_size >ice_max_xdp_frame_size (vsi)) {
@@ -3024,8 +3024,11 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,return 0 ; } + if_running =netif_running (vsi->netdev) && + !test_and_set_bit (ICE_VSI_DOWN , vsi->state); +/* need to stop netdev while setting up the program for Rx rings */ -if (if_running && !test_and_set_bit (ICE_VSI_DOWN , vsi->state)) { +if (if_running) { ret =ice_down (vsi);if (ret) {NL_SET_ERR_MSG_MOD (extack,"Preparing device for XDP attach failed" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 187/375 usbnet: modern method to get random MAC
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit bab8eb0dd4cb995caa4a0529d5655531c2ec5e8e ]
The driver generates a random MAC once on load and uses it over and over, including on two devices needing a random MAC at the same time.
Jakub suggested revamping the driver to the modern API for setting a random MAC rather than fixing the old stuff.
The bug is as old as the driver.
--- drivers/net/usb/usbnet.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/net/usb/usbnet.c +3 -8
@@ -61,9 +61,6 @@/*-------------------------------------------------------------------------*/ -// randomly generated ethernet address -static u8 node_id [ETH_ALEN ]; -/* use ethtool to change the level for any given device */ static int msg_level =-1 ;module_param (msg_level, int,0 );
@@ -1725,7 +1722,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->net = net;strscpy (net->name,"usb%d" ,sizeof (net->name)); -eth_hw_addr_set (net, node_id);/* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case.
@@ -1801,9 +1797,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) goto out4; } -/* let userspace know we have a random address */ -if (ether_addr_equal (net->dev_addr, node_id)) - net->addr_assign_type =NET_ADDR_RANDOM ; +/* this flags the device for user space */ +if (!is_valid_ether_addr (net->dev_addr)) +eth_hw_addr_random (net);if ((dev->driver_info->flags &FLAG_WLAN ) !=0 )SET_NETDEV_DEVTYPE (net, &wlan_type);
@@ -2211,7 +2207,6 @@ static int __init usbnet_init(void) BUILD_BUG_ON( sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data)); -eth_random_addr (node_id);return 0 ; }module_init (usbnet_init);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 188/375 net: dqs: Do not use extern for unused dql_group
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <[email protected]>
[ Upstream commit 77461c10819103eaee7b33c744174b32a8c78b40 ]
When CONFIG_DQL is not enabled, dql_group should be treated as a dead declaration. However, its current extern declaration assumes the linker will ignore it, which is generally true across most compiler and architecture combinations.
But in certain cases, the linker still attempts to resolve the extern struct, even when the associated code is dead, resulting in a linking error. For instance the following error in loongarch64:
Quoted 1 line
Quoted 1 line
loongarch64-linux-ld: net-sysfs.c:(.text+0x589c): undefined reference to `dql_group'
Modify the declaration of the dead object to be an empty declaration instead of an extern. This change will prevent the linker from attempting to resolve an undefined reference.
--- net/core/net-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/net-sysfs.c +1 -1
@@ -1524,7 +1524,7 @@ static const struct attribute_group dql_group = { };#else /* Fake declaration, all the code using it should be dead */ -extern const struct attribute_group dql_group; +static const struct attribute_group dql_group = {};#endif /* CONFIG_BQL */ #ifdef CONFIG_XPS
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 189/375 bpf, net: Fix a potential race in do_sock_getsockopt()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tze-nan Wu <[email protected]>
[ Upstream commit 33f339a1ba54e56bba57ee9a77c71e385ab4825c ]
There's a potential race when cgroup_bpf_enabled(CGROUP_GETSOCKOPT) is false during the execution of BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN, but becomes true when BPF_CGROUP_RUN_PROG_GETSOCKOPT is called. This inconsistency can lead to BPF_CGROUP_RUN_PROG_GETSOCKOPT receiving an "-EFAULT" from __cgroup_bpf_run_filter_getsockopt(max_optlen=0). Scenario shown as below:
process A process B
----------- ------------
BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN
enable CGROUP_GETSOCKOPT
BPF_CGROUP_RUN_PROG_GETSOCKOPT (-EFAULT)
To resolve this, remove the BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN macro and directly uses copy_from_sockptr to ensure that max_optlen is always set before BPF_CGROUP_RUN_PROG_GETSOCKOPT is invoked.
--- include/linux/bpf-cgroup.h | 9 --------- net/socket.c | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-)
include/linux/bpf-cgroup.h +0 -9
@@ -390,14 +390,6 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk, __ret; \ }) -#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN (optlen) \ -({ \ - int __ret = 0; \ - if (cgroup_bpf_enabled(CGROUP_GETSOCKOPT)) \ - copy_from_sockptr(&__ret, optlen, sizeof(int)); \ - __ret; \ -}) -#define BPF_CGROUP_RUN_PROG_GETSOCKOPT (sock, level, optname, optval, optlen, \ max_optlen, retval) \ ({ \
@@ -518,7 +510,6 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,#define BPF_CGROUP_RUN_PROG_SOCK_OPS (sock_ops) ({ 0; })#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP (atype, major, minor, access) ({ 0; })#define BPF_CGROUP_RUN_PROG_SYSCTL (head,table,write,buf,count,pos) ({ 0; }) -#define BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN (optlen) ({ 0; })#define BPF_CGROUP_RUN_PROG_GETSOCKOPT (sock, level, optname, optval, \ optlen, max_optlen, retval) ({ retval; }) #define BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sock, level, optname, optval, \
net/socket.c +2 -2
@@ -2350,7 +2350,7 @@ INDIRECT_CALLABLE_DECLARE(bool tcp_bpf_bypass_getsockopt(int level,int do_sock_getsockopt (struct socket *sock,bool compat,int level,int optname,sockptr_t optval,sockptr_t optlen) { -int max_optlen__maybe_unused ; +int max_optlen__maybe_unused =0 ;const struct proto_ops *ops;int err;
@@ -2359,7 +2359,7 @@ int do_sock_getsockopt(struct socket *sock, bool compat, int level,return err;if (!compat) - max_optlen =BPF_CGROUP_GETSOCKOPT_MAX_OPTLEN (optlen); +copy_from_sockptr (&max_optlen, optlen,sizeof (int )); ops =READ_ONCE (sock->ops);if (level ==SOL_SOCKET ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 190/375 bpf: add check for invalid name in btf_name_valid_section()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
[ Upstream commit bb6705c3f93bed2af03d43691743d4c43e3c8e6f ]
If the length of the name string is 1 and the value of name[0] is NULL byte, an OOB vulnerability occurs in btf_name_valid_section() and the return value is true, so the invalid name passes the check.
To solve this, you need to check if the first position is NULL byte and if the first character is printable.
--- kernel/bpf/btf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/bpf/btf.c +3 -1
@@ -817,9 +817,11 @@ static bool btf_name_valid_section(const struct btf *btf, u32 offset)const char *src =btf_str_by_offset (btf, offset);const char *src_limit; +if (!*src) +return false; +/* set a limit on identifier length */ src_limit = src +KSYM_NAME_LEN ; - src++;while (*src && src < src_limit) {if (!isprint (*src))return false;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 191/375 bareudp: Fix device stats updates.
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
[ Upstream commit 4963d2343af81f493519f9c3ea9f2169eaa7353a ]
Bareudp devices update their stats concurrently.
Therefore they need proper atomic increments.
--- drivers/net/bareudp.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/net/bareudp.c +11 -11
@@ -83,7 +83,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)if (skb_copy_bits (skb,BAREUDP_BASE_HLEN , &ipversion,sizeof (ipversion))) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } ipversion >>=4 ;
@@ -93,7 +93,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) }else if (ipversion ==6 && bareudp->multi_proto_mode) { proto =htons (ETH_P_IPV6 ); }else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }else if (bareudp->ethertype ==htons (ETH_P_MPLS_UC )) {
@@ -107,7 +107,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) ipv4_is_multicast(tunnel_hdr->daddr)) { proto = htons(ETH_P_MPLS_MC); } else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }else {
@@ -123,7 +123,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) (addr_type & IPV6_ADDR_MULTICAST)) { proto = htons(ETH_P_MPLS_MC); } else { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; } }
@@ -135,7 +135,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) proto, !net_eq(bareudp->net, dev_net(bareudp->dev)))) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; }
@@ -143,7 +143,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) tun_dst =udp_tun_rx_dst (skb, family, key,0 ,0 );if (!tun_dst) { - bareudp->dev->stats.rx_dropped++; +DEV_STATS_INC (bareudp->dev, rx_dropped); goto drop; }skb_dst_set (skb, &tun_dst->dst);
@@ -169,8 +169,8 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) &((struct ipv6hdr *)oiph)->saddr); }if (err >1 ) { - ++bareudp->dev->stats.rx_frame_errors; - ++bareudp->dev->stats.rx_errors; +DEV_STATS_INC (bareudp->dev, rx_frame_errors); +DEV_STATS_INC (bareudp->dev, rx_errors); goto drop; } }
@@ -467,11 +467,11 @@ static netdev_tx_t bareudp_xmit(struct sk_buff *skb, struct net_device *dev)dev_kfree_skb (skb);if (err == -ELOOP ) - dev->stats.collisions++; +DEV_STATS_INC (dev, collisions);else if (err == -ENETUNREACH ) - dev->stats.tx_carrier_errors++; +DEV_STATS_INC (dev, tx_carrier_errors); - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);return NETDEV_TX_OK ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 192/375 fou: Fix null-ptr-deref in GRO.
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 7e4196935069947d8b70b09c1660b67b067e75cb ]
We observed a null-ptr-deref in fou_gro_receive() while shutting down a host. [0]
The NULL pointer is sk->sk_user_data, and the offset 8 is of protocol in struct fou.
When fou_release() is called due to netns dismantle or explicit tunnel teardown, udp_tunnel_sock_release() sets NULL to sk->sk_user_data. Then, the tunnel socket is destroyed after a single RCU grace period.
So, in-flight udp4_gro_receive() could find the socket and execute the FOU GRO handler, where sk->sk_user_data could be NULL.
Let's use rcu_dereference_sk_user_data() in fou_from_sock() and add NULL checks in FOU GRO handlers.
[0]:
BUG: kernel NULL pointer dereference, address: 0000000000000008 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 80000001032f4067 P4D 80000001032f4067 PUD 103240067 PMD 0 SMP PTI CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.216-204.855.amzn2.x86_64 #1 Hardware name: Amazon EC2 c5.large/, BIOS 1.0 10/16/2017 RIP: 0010:fou_gro_receive (net/ipv4/fou.c:233) [fou] Code: 41 5f c3 cc cc cc cc e8 e7 2e 69 f4 0f 1f 80 00 00 00 00 0f 1f 44 00 00 49 89 f8 41 54 48 89 f7 48 89 d6 49 8b 80 88 02 00 00 <0f> b6 48 08 0f b7 42 4a 66 25 fd fd 80 cc 02 66 89 42 4a 0f b6 42 RSP: 0018:ffffa330c0003d08 EFLAGS: 00010297 RAX: 0000000000000000 RBX: ffff93d9e3a6b900 RCX: 0000000000000010 RDX: ffff93d9e3a6b900 RSI: ffff93d9e3a6b900 RDI: ffff93dac2e24d08 RBP: ffff93d9e3a6b900 R08: ffff93dacbce6400 R09: 0000000000000002 R10: 0000000000000000 R11: ffffffffb5f369b0 R12: ffff93dacbce6400 R13: ffff93dac2e24d08 R14: 0000000000000000 R15: ffffffffb4edd1c0 FS: 0000000000000000(0000) GS:ffff93daee800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000008 CR3: 0000000102140001 CR4: 00000000007706f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <IRQ> ? show_trace_log_lvl (arch/x86/kernel/dumpstack.c:259) ? __die_body.cold (arch/x86/kernel/dumpstack.c:478 arch/x86/kernel/dumpstack.c:420) ? no_context (arch/x86/mm/fault.c:752) ? exc_page_fault (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 arch/x86/mm/fault.c:1435 arch/x86/mm/fault.c:1483) ? asm_exc_page_fault (arch/x86/include/asm/idtentry.h:571) ? fou_gro_receive (net/ipv4/fou.c:233) [fou] udp_gro_receive (include/linux/netdevice.h:2552 net/ipv4/udp_offload.c:559) udp4_gro_receive (net/ipv4/udp_offload.c:604) inet_gro_receive (net/ipv4/af_inet.c:1549 (discriminator 7)) dev_gro_receive (net/core/dev.c:6035 (discriminator 4)) napi_gro_receive (net/core/dev.c:6170) ena_clean_rx_irq (drivers/amazon/net/ena/ena_netdev.c:1558) [ena] ena_io_poll (drivers/amazon/net/ena/ena_netdev.c:1742) [ena] napi_poll (net/core/dev.c:6847) net_rx_action (net/core/dev.c:6917) __do_softirq (arch/x86/include/asm/jump_label.h:25 include/linux/jump_label.h:200 include/trace/events/irq.h:142 kernel/softirq.c:299) asm_call_irq_on_stack (arch/x86/entry/entry_64.S:809) </IRQ> do_softirq_own_stack (arch/x86/include/asm/irq_stack.h:27 arch/x86/include/asm/irq_stack.h:77 arch/x86/kernel/irq_64.c:77) irq_exit_rcu (kernel/softirq.c:393 kernel/softirq.c:423 kernel/softirq.c:435) common_interrupt (arch/x86/kernel/irq.c:239) asm_common_interrupt (arch/x86/include/asm/idtentry.h:626) RIP: 0010:acpi_idle_do_entry (arch/x86/include/asm/irqflags.h:49 arch/x86/include/asm/irqflags.h:89 drivers/acpi/processor_idle.c:114 drivers/acpi/processor_idle.c:575) Code: 8b 15 d1 3c c4 02 ed c3 cc cc cc cc 65 48 8b 04 25 40 ef 01 00 48 8b 00 a8 08 75 eb 0f 1f 44 00 00 0f 00 2d d5 09 55 00 fb f4 <fa> c3 cc cc cc cc e9 be fc ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 RSP: 0018:ffffffffb5603e58 EFLAGS: 00000246 RAX: 0000000000004000 RBX: ffff93dac0929c00 RCX: ffff93daee833900 RDX: ffff93daee800000 RSI: ffff93daee87dc00 RDI: ffff93daee87dc64 RBP: 0000000000000001 R08: ffffffffb5e7b6c0 R09: 0000000000000044 R10: ffff93daee831b04 R11: 00000000000001cd R12: 0000000000000001 R13: ffffffffb5e7b740 R14: 0000000000000001 R15: 0000000000000000 ? sched_clock_cpu (kernel/sched/clock.c:371) acpi_idle_enter (drivers/acpi/processor_idle.c:712 (discriminator 3)) cpuidle_enter_state (drivers/cpuidle/cpuidle.c:237) cpuidle_enter (drivers/cpuidle/cpuidle.c:353) cpuidle_idle_call (kernel/sched/idle.c:158 kernel/sched/idle.c:239) do_idle (kernel/sched/idle.c:302) cpu_startup_entry (kernel/sched/idle.c:395 (discriminator 1)) start_kernel (init/main.c:1048) secondary_startup_64_no_verify (arch/x86/kernel/head_64.S:310) Modules linked in: udp_diag tcp_diag inet_diag nft_nat ipip tunnel4 dummy fou ip_tunnel nft_masq nft_chain_nat nf_nat wireguard nft_ct curve25519_x86_64 libcurve25519_generic nf_conntrack libchacha20poly1305 nf_defrag_ipv6 nf_defrag_ipv4 nft_objref chacha_x86_64 nft_counter nf_tables nfnetlink poly1305_x86_64 ip6_udp_tunnel udp_tunnel libchacha crc32_pclmul ghash_clmulni_intel aesni_intel crypto_simd cryptd glue_helper mousedev psmouse button ena ptp pps_core crc32c_intel
CR2: 0000000000000008
--- net/ipv4/fou_core.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
net/ipv4/fou_core.c +24 -5
@@ -50,7 +50,7 @@ struct fou_net {static inline struct fou *fou_from_sock (struct sock *sk) { -return sk->sk_user_data; +return rcu_dereference_sk_user_data (sk); }static int fou_recv_pull (struct sk_buff *skb,struct fou *fou,size_t len)
@@ -233,9 +233,15 @@ static struct sk_buff *fou_gro_receive(struct sock *sk, struct sk_buff *skb) {const struct net_offload __rcu **offloads; -u8 proto =fou_from_sock (sk)->protocol; +struct fou *fou =fou_from_sock (sk);const struct net_offload *ops;struct sk_buff *pp =NULL ; +u8 proto; + +if (!fou) + goto out; + + proto = fou->protocol;/* We can clear the encap_mark for FOU as we are essentially doing * one of two possible things. We are either adding an L4 tunnel
@@ -263,14 +269,24 @@ static int fou_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) {const struct net_offload __rcu **offloads; -u8 proto =fou_from_sock (sk)->protocol; +struct fou *fou =fou_from_sock (sk);const struct net_offload *ops; -int err = -ENOSYS ; +u8 proto; +int err; + +if (!fou) { + err = -ENOENT ; + goto out; + } + + proto = fou->protocol; offloads =NAPI_GRO_CB (skb)->is_ipv6 ? inet6_offloads : inet_offloads; ops =rcu_dereference (offloads[proto]); -if (WARN_ON (!ops || !ops->callbacks.gro_complete)) +if (WARN_ON (!ops || !ops->callbacks.gro_complete)) { + err = -ENOSYS ; goto out; + } err = ops->callbacks.gro_complete (skb, nhoff);
@@ -320,6 +336,9 @@ static struct sk_buff *gue_gro_receive(struct sock *sk,struct gro_remcsum grc;u8 proto; +if (!fou) + goto out; +skb_gro_remcsum_init (&grc); off =skb_gro_offset (skb);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 193/375 r8152: fix the firmware doesnt work
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hayes Wang <[email protected]>
[ Upstream commit 8487b4af59d4d7feda4b119dc2d92c67ca25c27e ]
generic_ocp_write() asks the parameter "size" must be 4 bytes align. Therefore, write the bp would fail, if the mac->bp_num is odd. Align the size to 4 for fixing it. The way may write an extra bp, but the rtl8152_is_fw_mac_ok() makes sure the value must be 0 for the bp whose index is more than mac->bp_num. That is, there is no influence for the firmware.
Besides, I check the return value of generic_ocp_write() to make sure everything is correct.
--- drivers/net/usb/r8152.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/net/usb/r8152.c +13 -4
@@ -5177,14 +5177,23 @@ static void rtl8152_fw_mac_apply(struct r8152 *tp, struct fw_mac *mac) data = (u8 *)mac; data +=__le16_to_cpu (mac->fw_offset); -generic_ocp_write (tp,__le16_to_cpu (mac->fw_reg),0xff , length, data, - type); +if (generic_ocp_write (tp,__le16_to_cpu (mac->fw_reg),0xff , length, + data, type) <0 ) { +dev_err (&tp->intf->dev,"Write %s fw fail\n" , + type ?"PLA" :"USB" ); +return ; + }ocp_write_word (tp, type,__le16_to_cpu (mac->bp_ba_addr),__le16_to_cpu (mac->bp_ba_value)); -generic_ocp_write (tp,__le16_to_cpu (mac->bp_start),BYTE_EN_DWORD , -__le16_to_cpu (mac->bp_num) <<1 , mac->bp, type); +if (generic_ocp_write (tp,__le16_to_cpu (mac->bp_start),BYTE_EN_DWORD , +ALIGN (__le16_to_cpu (mac->bp_num) <<1 ,4 ), + mac->bp, type) <0 ) { +dev_err (&tp->intf->dev,"Write %s bp fail\n" , + type ?"PLA" :"USB" ); +return ; + } bp_en_addr =__le16_to_cpu (mac->bp_en_addr);if (bp_en_addr)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 194/375 net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Gorski <[email protected]>
[ Upstream commit bee2ef946d3184e99077be526567d791c473036f ]
When userspace wants to take over a fdb entry by setting it as EXTERN_LEARNED, we set both flags BR_FDB_ADDED_BY_EXT_LEARN and BR_FDB_ADDED_BY_USER in br_fdb_external_learn_add().
If the bridge updates the entry later because its port changed, we clear the BR_FDB_ADDED_BY_EXT_LEARN flag, but leave the BR_FDB_ADDED_BY_USER flag set.
If userspace then wants to take over the entry again, br_fdb_external_learn_add() sees that BR_FDB_ADDED_BY_USER and skips setting the BR_FDB_ADDED_BY_EXT_LEARN flags, thus silently ignores the update.
Fix this by always allowing to set BR_FDB_ADDED_BY_EXT_LEARN regardless if this was a user fdb entry or not.
--- net/bridge/br_fdb.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/bridge/br_fdb.c +2 -4
@@ -1469,12 +1469,10 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, modified = true; } -if (test_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags)) { +if (test_and_set_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags)) {/* Refresh entry */ fdb->used = jiffies; - }else if (!test_bit (BR_FDB_ADDED_BY_USER , &fdb->flags)) { -/* Take over SW learned entry */ -set_bit (BR_FDB_ADDED_BY_EXT_LEARN , &fdb->flags); + }else { modified = true; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 195/375 net: xilinx: axienet: Fix race in axienet_stop
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit 858430db28a5f5a11f8faa3a6fa805438e6f0851 ]
axienet_dma_err_handler can race with axienet_stop in the following manner:
CPU 1 CPU 2
====================== ==================axienet_stop()
napi_disable()
axienet_dma_stop()
axienet_dma_err_handler()
napi_disable()
axienet_dma_stop()
axienet_dma_start()
napi_enable()
cancel_work_sync()
free_irq()Fix this by setting a flag in axienet_stop telling axienet_dma_err_handler not to bother doing anything. I chose not to use disable_work_sync to allow for easier backporting.
--- drivers/net/ethernet/xilinx/xilinx_axienet.h | 3 +++ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 8 ++++++++ 2 files changed, 11 insertions(+)
drivers/net/ethernet/xilinx/xilinx_axienet.h +3 -0
@@ -436,6 +436,8 @@ struct skbuf_dma_descriptor {* @tx_bytes: TX byte count for statistics * @tx_stat_sync: Synchronization object for TX stats * @dma_err_task: Work structure to process Axi DMA errors +* @stopping: Set when @dma_err_task shouldn't do anything because we are +* about to stop the device. * @tx_irq: Axidma TX IRQ number * @rx_irq: Axidma RX IRQ number * @eth_irq: Ethernet core IRQ number
@@ -507,6 +509,7 @@ struct axienet_local {struct u64_stats_sync tx_stat_sync;struct work_struct dma_err_task; +bool stopping;int tx_irq;int rx_irq;
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +8 -0
@@ -1460,6 +1460,7 @@ static int axienet_init_legacy_dma(struct net_device *ndev)struct axienet_local *lp =netdev_priv (ndev);/* Enable worker thread for Axi DMA error handling */ + lp->stopping = false;INIT_WORK (&lp->dma_err_task, axienet_dma_err_handler);napi_enable (&lp->napi_rx);
@@ -1580,6 +1581,9 @@ static int axienet_stop(struct net_device *ndev)dev_dbg (&ndev->dev,"axienet_close()\n" );if (!lp->use_dmaengine) { +WRITE_ONCE (lp->stopping, true); +flush_work (&lp->dma_err_task); +napi_disable (&lp->napi_tx);napi_disable (&lp->napi_rx); }
@@ -2154,6 +2158,10 @@ static void axienet_dma_err_handler(struct work_struct *work) dma_err_task);struct net_device *ndev = lp->ndev; +/* Don't bother if we are going to stop anyway */ +if (READ_ONCE (lp->stopping)) +return ; +napi_disable (&lp->napi_tx);napi_disable (&lp->napi_rx);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 196/375 net: dsa: vsc73xx: fix possible subblocks range of CAPT block
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pawel Dembicki <[email protected]>
[ Upstream commit 8e69c96df771ab469cec278edb47009351de4da6 ]
CAPT block (CPU Capture Buffer) have 7 sublocks: 0-3, 4, 6, 7. Function 'vsc73xx_is_addr_valid' allows to use only block 0 at this moment.
This patch fix it.
--- drivers/net/dsa/vitesse-vsc73xx-core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/net/dsa/vitesse-vsc73xx-core.c +8 -2
@@ -34,7 +34,7 @@#define VSC73XX_BLOCK_ANALYZER 0x2/* Only subblock 0 */ #define VSC73XX_BLOCK_MII 0x3/* Subblocks 0 and 1 */ #define VSC73XX_BLOCK_MEMINIT 0x3/* Only subblock 2 */ -#define VSC73XX_BLOCK_CAPTURE 0x4/* Only subblock 2 */ +#define VSC73XX_BLOCK_CAPTURE 0x4/* Subblocks 0-4, 6, 7 */ #define VSC73XX_BLOCK_ARBITER 0x5/* Only subblock 0 */ #define VSC73XX_BLOCK_SYSTEM 0x7/* Only subblock 0 */
@@ -370,13 +370,19 @@ int vsc73xx_is_addr_valid(u8 block, u8 subblock)break ;case VSC73XX_BLOCK_MII : -case VSC73XX_BLOCK_CAPTURE :case VSC73XX_BLOCK_ARBITER :switch (subblock) { case 0 ... 1:return 1 ; }break ; +case VSC73XX_BLOCK_CAPTURE : +switch (subblock) { + case 0 ... 4: + case 6 ... 7: +return 1 ; + } +break ; }return 0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 197/375 selftests: net: enable bind tests
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamie Bainbridge <[email protected]>
[ Upstream commit e4af74a53b7aa865e7fcc104630ebb7a9129b71f ]
bind_wildcard is compiled but not run, bind_timewait is not compiled.
These two tests complete in a very short time, use the test harness properly, and seem reasonable to enable.
The author of the tests confirmed via email that these were intended to be run.
Enable these two tests.
--- tools/testing/selftests/net/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/net/Makefile +2 -1
@@ -84,7 +84,8 @@ TEST_GEN_PROGS += so_incoming_cpu TEST_PROGS += sctp_vrf.sh TEST_GEN_FILES += sctp_hello TEST_GEN_FILES += ip_local_port_range -TEST_GEN_FILES += bind_wildcard +TEST_GEN_PROGS += bind_wildcard +TEST_GEN_PROGS += bind_timewait TEST_PROGS += test_vxlan_mdb.sh TEST_PROGS += test_bridge_neigh_suppress.sh TEST_PROGS += test_vxlan_nolocalbypass.sh
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 198/375 tools/net/ynl: fix cli.py --subscribe feature
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arkadiusz Kubalewski <[email protected]>
[ Upstream commit 6fda63c45fe8a0870226c13dcce1cc21b7c4d508 ]
Execution of command:./tools/net/ynl/cli.py --spec Documentation/netlink/specs/dpll.yaml /
--subscribe "monitor" --sleep 10
fails with:
File "/repo/./tools/net/ynl/cli.py", line 109, in main
ynl.check_ntf()
File "/repo/tools/net/ynl/lib/ynl.py", line 924, in check_ntf
op = self.rsp_by_value[nl_msg.cmd()]KeyError: 19
Parsing Generic Netlink notification messages performs lookup for op in the message. The message was not yet decoded, and is not yet considered GenlMsg, thus msg.cmd() returns Generic Netlink family id (19) instead of proper notification command id (i.e.: DPLL_CMD_PIN_CHANGE_NTF=13).
Allow the op to be obtained within NetlinkProtocol.decode(..) itself if the op was not passed to the decode function, thus allow parsing of Generic Netlink notifications without causing the failure.
--- tools/net/ynl/lib/ynl.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
tools/net/ynl/lib/ynl.py +4 -3
@@ -388,6 +388,8 @@ class NetlinkProtocol: def decode(self, ynl, nl_msg, op): msg = self._decode(nl_msg) + if op is None: + op = ynl.rsp_by_value[msg.cmd()] fixed_header_size = ynl._struct_size(op.fixed_header) msg.raw_attrs = NlAttrs(msg.raw, fixed_header_size) return msg
@@ -919,8 +921,7 @@ class YnlFamily(SpecFamily): print("Netlink done while checking for ntf!?") continue - op = self.rsp_by_value[nl_msg.cmd()] - decoded = self.nlproto.decode(self, nl_msg, op) + decoded = self.nlproto.decode(self, nl_msg, None) if decoded.cmd() not in self.async_msg_ids: print("Unexpected msg id done while checking for ntf", decoded) continue
@@ -978,7 +979,7 @@ class YnlFamily(SpecFamily): if nl_msg.extack: self._decode_extack(req_msg, op, nl_msg.extack) else: - op = self.rsp_by_value[nl_msg.cmd()] + op = None req_flags = [] if nl_msg.error:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 199/375 xen: privcmd: Fix possible access to a freed kirqfd instance
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viresh Kumar <[email protected]>
[ Upstream commit 611ff1b1ae989a7bcce3e2a8e132ee30e968c557 ]
Nothing prevents simultaneous ioctl calls to privcmd_irqfd_assign() and privcmd_irqfd_deassign(). If that happens, it is possible that a kirqfd created and added to the irqfds_list by privcmd_irqfd_assign() may get removed by another thread executing privcmd_irqfd_deassign(), while the former is still using it after dropping the locks.
This can lead to a situation where an already freed kirqfd instance may be accessed and cause kernel oops.
Use SRCU locking to prevent the same, as is done for the KVM implementation for irqfds.
--- drivers/xen/privcmd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/xen/privcmd.c +9 -1
@@ -17,6 +17,7 @@#include <linux/poll.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/srcu.h> #include <linux/string.h> #include <linux/workqueue.h> #include <linux/errno.h>
@@ -846,6 +847,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,/* Irqfd support */ static struct workqueue_struct *irqfd_cleanup_wq;static DEFINE_SPINLOCK (irqfds_lock); +DEFINE_STATIC_SRCU (irqfds_srcu);static LIST_HEAD (irqfds_list);struct privcmd_kernel_irqfd {
@@ -873,6 +875,9 @@ static void irqfd_shutdown(struct work_struct *work) container_of(work, struct privcmd_kernel_irqfd, shutdown);u64 cnt; +/* Make sure irqfd has been initialized in assign path */ +synchronize_srcu (&irqfds_srcu); +eventfd_ctx_remove_wait_queue (kirqfd->eventfd, &kirqfd->wait, &cnt);eventfd_ctx_put (kirqfd->eventfd);kfree (kirqfd);
@@ -935,7 +940,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)__poll_t events;struct fd f;void *dm_op; -int ret; +int ret, idx; kirqfd =kzalloc (sizeof (*kirqfd) + irqfd->size,GFP_KERNEL );if (!kirqfd)
@@ -981,6 +986,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) } } + idx =srcu_read_lock (&irqfds_srcu);list_add_tail (&kirqfd->list, &irqfds_list);spin_unlock_irqrestore (&irqfds_lock, flags);
@@ -992,6 +998,8 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)if (events &EPOLLIN )irqfd_inject (kirqfd); +srcu_read_unlock (&irqfds_srcu, idx); +/* * Do not drop the file until the kirqfd is fully initialized, otherwise * we might race against the EPOLLHUP.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 200/375 firmware: cs_dsp: Dont allow writes to read-only controls
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit 62412a9357b16a4e39dc582deb2e2a682b92524c ]
Add a check to cs_dsp_coeff_write_ctrl() to abort if the control is not writeable.
The cs_dsp code originated as an ASoC driver (wm_adsp) where all controls were exported as ALSA controls. It relied on ALSA to enforce the read-only permission. Now that the code has been separated from ALSA/ASoC it must perform its own permission check.
This isn't currently causing any problems so there shouldn't be any need to backport this. If the client of cs_dsp exposes the control as an ALSA control, it should set permissions on that ALSA control to protect it. The few uses of cs_dsp_coeff_write_ctrl() inside drivers are for writable controls.
--- drivers/firmware/cirrus/cs_dsp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/firmware/cirrus/cs_dsp.c +3 -0
@@ -796,6 +796,9 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl,lockdep_assert_held (&ctl->dsp->pwr_lock); +if (ctl->flags && !(ctl->flags &WMFW_CTL_FLAG_WRITEABLE )) +return -EPERM ; +if (len + off *sizeof (u32) > ctl->len)return -EINVAL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 201/375 phy: zynqmp: Take the phy mutex in xlate
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Anderson <[email protected]>
[ Upstream commit d79c6840917097285e03a49f709321f5fb972750 ]
Take the phy mutex in xlate to protect against concurrent modification/access to gtr_phy. This does not typically cause any issues, since in most systems the phys are only xlated once and thereafter accessed with the phy API (which takes the locks). However, we are about to allow userspace to access phys for debugging, so it's important to avoid any data races.
--- drivers/phy/xilinx/phy-zynqmp.c | 1 + 1 file changed, 1 insertion(+)
drivers/phy/xilinx/phy-zynqmp.c +1 -0
@@ -846,6 +846,7 @@ static struct phy *xpsgtr_xlate(struct device *dev, phy_type = args->args[1 ]; phy_instance = args->args[2 ]; +guard (mutex)(>r_phy->phy->mutex); ret =xpsgtr_set_lane_type (gtr_phy, phy_type, phy_instance);if (ret <0 ) {dev_err (gtr_dev->dev,"Invalid PHY type and/or instance\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 202/375 ASoC: topology: Properly initialize soc_enum values
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amadeusz Sławiński <[email protected]>
[ Upstream commit 8ec2a2643544ce352f012ad3d248163199d05dfc ]
soc_tplg_denum_create_values() should properly set its values field.
--- sound/soc/soc-topology.c | 2 ++ 1 file changed, 2 insertions(+)
sound/soc/soc-topology.c +2 -0
@@ -851,6 +851,8 @@ static int soc_tplg_denum_create_values(struct soc_tplg *tplg, struct soc_enum * se->dobj.control.dvalues[i] =le32_to_cpu (ec->values[i]); } + se->items =le32_to_cpu (ec->items); + se->values = (const unsigned int *)se->dobj.control.dvalues;return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 203/375 dm init: Handle minors larger than 255
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Marzinski <[email protected]>
[ Upstream commit 140ce37fd78a629105377e17842465258a5459ef ]
dm_parse_device_entry() simply copies the minor number into dmi.dev, but the dev_t format splits the minor number between the lowest 8 bytes and highest 12 bytes. If the minor number is larger than 255, part of it will end up getting treated as the major number
Fix this by checking that the minor number is valid and then encoding it as a dev_t.
--- drivers/md/dm-init.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/md/dm-init.c +3 -1
@@ -212,8 +212,10 @@ static char __init *dm_parse_device_entry(struct dm_device *dev, char *str)strscpy (dev->dmi.uuid, field[1 ],sizeof (dev->dmi.uuid));/* minor */ if (strlen (field[2 ])) { -if (kstrtoull (field[2 ],0 , &dev->dmi.dev)) +if (kstrtoull (field[2 ],0 , &dev->dmi.dev) || + dev->dmi.dev >= (1 <<MINORBITS ))return ERR_PTR (-EINVAL ); + dev->dmi.dev =huge_encode_dev ((dev_t )dev->dmi.dev); dev->dmi.flags |=DM_PERSISTENT_DEV_FLAG ; }/* flags */
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 204/375 cxl/region: Fix a race condition in memory hotplug notifier
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huang Ying <[email protected]>
[ Upstream commit a3483ee7e6a7f2d12b5950246f4e0ef94f4a5df0 ]
In the memory hotplug notifier function of the CXL region, cxl_region_perf_attrs_callback(), the node ID is obtained by checking the host address range of the region. However, the address range information is not available when the region is registered in devm_cxl_add_region(). Additionally, this information may be removed or added under the protection of cxl_region_rwsem during runtime. If the memory notifier is called for nodes other than that backed by the region, a race condition may occur, potentially leading to a NULL dereference or an invalid address range.
The race condition is addressed by checking the availability of the address range information under the protection of cxl_region_rwsem. To enhance code readability and use guard(), the relevant code has been moved into a newly added function: cxl_region_nid().
--- drivers/cxl/core/region.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/cxl/core/region.c +15 -4
@@ -2386,14 +2386,25 @@ static bool cxl_region_update_coordinates(struct cxl_region *cxlr, int nid)return true; } +static int cxl_region_nid (struct cxl_region *cxlr) +{ +struct cxl_region_params *p = &cxlr->params; +struct cxl_endpoint_decoder *cxled; +struct cxl_decoder *cxld; + +guard (rwsem_read)(&cxl_region_rwsem); + cxled = p->targets[0 ]; +if (!cxled) +return NUMA_NO_NODE ; + cxld = &cxled->cxld; +return phys_to_target_node (cxld->hpa_range.start); +} +static int cxl_region_perf_attrs_callback (struct notifier_block *nb,unsigned long action,void *arg) { struct cxl_region *cxlr = container_of(nb, struct cxl_region, memory_notifier); -struct cxl_region_params *p = &cxlr->params; -struct cxl_endpoint_decoder *cxled = p->targets[0 ]; -struct cxl_decoder *cxld = &cxled->cxld;struct memory_notify *mnb = arg;int nid = mnb->status_change_nid;int region_nid;
@@ -2401,7 +2412,7 @@ static int cxl_region_perf_attrs_callback(struct notifier_block *nb,if (nid ==NUMA_NO_NODE || action !=MEM_ONLINE )return NOTIFY_DONE ; - region_nid =phys_to_target_node (cxld->hpa_range.start); + region_nid =cxl_region_nid (cxlr);if (nid != region_nid)return NOTIFY_DONE ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 205/375 iommu/vt-d: Handle volatile descriptor status read
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Pan <[email protected]>
[ Upstream commit b5e86a95541cea737394a1da967df4cd4d8f7182 ]
Queued invalidation wait descriptor status is volatile in that IOMMU hardware writes the data upon completion.
Use READ_ONCE() to prevent compiler optimizations which ensures memory reads every time. As a side effect, READ_ONCE() also enforces strict types and may add an extra instruction. But it should not have negative performance impact since we use cpu_relax anyway and the extra time(by adding an instruction) may allow IOMMU HW request cacheline ownership easier.
e.g. gcc 12.3
BEFORE:
81 38 ad de 00 00 cmpl $0x2,(%rax)
AFTER (with READ_ONCE())
772f: 8b 00 mov (%rax),%eax
7731: 3d ad de 00 00 cmp $0x2,%eax
//status data is 32 bit--- drivers/iommu/intel/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/dmar.c +1 -1
@@ -1446,7 +1446,7 @@ int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,*/ writel (qi->free_head << shift, iommu->reg +DMAR_IQT_REG ); -while (qi->desc_status[wait_index] !=QI_DONE ) { +while (READ_ONCE (qi->desc_status[wait_index]) !=QI_DONE ) {/* * We will leave the interrupts disabled, to prevent interrupt * context to queue another cmd while a cmd is already submitted
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 206/375 iommu/vt-d: Remove control over Execute-Requested requests
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Baolu <[email protected]>
[ Upstream commit e995fcde6070f0981e083c1e2e17e401e6c17ad9 ]
The VT-d specification has removed architectural support of the requests with pasid with a value of 1 for Execute-Requested (ER). And the NXE bit in the pasid table entry and XD bit in the first-stage paging Entries are deprecated accordingly.
Remove the programming of these bits to make it consistent with the spec.
--- drivers/iommu/intel/iommu.c | 4 ++-- drivers/iommu/intel/iommu.h | 6 ++---- drivers/iommu/intel/pasid.c | 1 - drivers/iommu/intel/pasid.h | 10 ---------- 4 files changed, 4 insertions(+), 17 deletions(-)
drivers/iommu/intel/iommu.c +2 -2
@@ -854,7 +854,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,domain_flush_cache (domain, tmp_page,VTD_PAGE_SIZE ); pteval = ((uint64_t )virt_to_dma_pfn (tmp_page) <<VTD_PAGE_SHIFT ) |DMA_PTE_READ |DMA_PTE_WRITE ;if (domain->use_first_level) - pteval |=DMA_FL_PTE_XD |DMA_FL_PTE_US |DMA_FL_PTE_ACCESS ; + pteval |=DMA_FL_PTE_US |DMA_FL_PTE_ACCESS ; tmp =0ULL ;if (!try_cmpxchg64 (&pte->val, &tmp, pteval))
@@ -1872,7 +1872,7 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, attr = prot & (DMA_PTE_READ |DMA_PTE_WRITE |DMA_PTE_SNP ); attr |=DMA_FL_PTE_PRESENT ;if (domain->use_first_level) { - attr |=DMA_FL_PTE_XD |DMA_FL_PTE_US |DMA_FL_PTE_ACCESS ; + attr |=DMA_FL_PTE_US |DMA_FL_PTE_ACCESS ;if (prot &DMA_PTE_WRITE ) attr |=DMA_FL_PTE_DIRTY ; }
drivers/iommu/intel/iommu.h +2 -4
@@ -49,7 +49,6 @@#define DMA_FL_PTE_US BIT_ULL(2)#define DMA_FL_PTE_ACCESS BIT_ULL(5)#define DMA_FL_PTE_DIRTY BIT_ULL(6) -#define DMA_FL_PTE_XD BIT_ULL(63)#define DMA_SL_PTE_DIRTY_BIT 9#define DMA_SL_PTE_DIRTY BIT_ULL(DMA_SL_PTE_DIRTY_BIT)
@@ -831,11 +830,10 @@ static inline void dma_clear_pte(struct dma_pte *pte)static inline u64 dma_pte_addr (struct dma_pte *pte) {#ifdef CONFIG_64BIT -return pte->val &VTD_PAGE_MASK & (~DMA_FL_PTE_XD ); +return pte->val &VTD_PAGE_MASK ;#else /* Must have a full atomic 64-bit read */ -return __cmpxchg64 (&pte->val,0ULL ,0ULL ) & -VTD_PAGE_MASK & (~DMA_FL_PTE_XD ); +return __cmpxchg64 (&pte->val,0ULL ,0ULL ) &VTD_PAGE_MASK ;#endif }
drivers/iommu/intel/pasid.c +0 -1
@@ -333,7 +333,6 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,pasid_set_domain_id (pte, did);pasid_set_address_width (pte, iommu->agaw);pasid_set_page_snoop (pte, !!ecap_smpwc (iommu->ecap)); -pasid_set_nxe (pte);/* Setup Present and PASID Granular Transfer Type: */ pasid_set_translation_type (pte,PASID_ENTRY_PGTT_FL_ONLY );
drivers/iommu/intel/pasid.h +0 -10
@@ -247,16 +247,6 @@ static inline void pasid_set_page_snoop(struct pasid_entry *pe, bool value)pasid_set_bits (&pe->val[1 ],1 <<23 , value <<23 ); } -/* -* Setup No Execute Enable bit (Bit 133) of a scalable mode PASID -* entry. It is required when XD bit of the first level page table -* entry is about to be set. -*/ -static inline void pasid_set_nxe (struct pasid_entry *pe) -{ -pasid_set_bits (&pe->val[2 ],1 <<5 ,1 <<5 ); -} -/* * Setup the Page Snoop (PGSNP) field (Bit 88) of a scalable mode * PASID entry.
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 207/375 block: dont call bio_uninit from bio_endio
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <[email protected]>
[ Upstream commit bf4c89fc8797f5c0964a0c3d561fbe7e8483b62f ]
Commit b222dd2fdd53 ("block: call bio_uninit in bio_endio") added a call to bio_uninit in bio_endio to work around callers that use bio_init but fail to call bio_uninit after they are done to release the resources. While this is an abuse of the bio_init API we still have quite a few of those left. But this early uninit causes a problem for integrity data, as at least some users need the bio_integrity_payload. Right now the only one is the NVMe passthrough which archives this by adding a special case to skip the freeing if the BIP_INTEGRITY_USER flag is set.
Sort this out by only putting bi_blkg in bio_endio as that is the cause of the actual leaks - the few users of the crypto context and integrity data all properly call bio_uninit, usually through bio_put for dynamically allocated bios.
--- block/bio.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
block/bio.c +12 -2
@@ -1630,8 +1630,18 @@ void bio_endio(struct bio *bio) goto again; } -/* release cgroup info */ -bio_uninit (bio); +#ifdef CONFIG_BLK_CGROUP +/* +* Release cgroup info. We shouldn't have to do this here, but quite +* a few callers of bio_init fail to call bio_uninit, so we cover up +* for that here at least for now. +*/ +if (bio->bi_blkg) { +blkg_put (bio->bi_blkg); + bio->bi_blkg =NULL ; + } +#endif +if (bio->bi_end_io) bio->bi_end_io (bio); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 208/375 cgroup: Protect css->cgroup write under css_set_lock
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 57b56d16800e8961278ecff0dc755d46c4575092 ]
The writing of css->cgroup associated with the cgroup root in rebind_subsystems() is currently protected only by cgroup_mutex. However, the reading of css->cgroup in both proc_cpuset_show() and proc_cgroup_show() is protected just by css_set_lock. That makes the readers susceptible to racing problems like data tearing or caching. It is also a problem that can be reported by KCSAN.
This can be fixed by using READ_ONCE() and WRITE_ONCE() to access css->cgroup. Alternatively, the writing of css->cgroup can be moved under css_set_lock as well which is done by this patch.
--- kernel/cgroup/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup/cgroup.c +1 -1
@@ -1839,9 +1839,9 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)RCU_INIT_POINTER (scgrp->subsys[ssid],NULL );rcu_assign_pointer (dcgrp->subsys[ssid], css); ss->root = dst_root; - css->cgroup = dcgrp;spin_lock_irq (&css_set_lock); + css->cgroup = dcgrp;WARN_ON (!list_empty (&dcgrp->e_csets[ss->id]));list_for_each_entry_safe (cset, cset_pos, &scgrp->e_csets[ss->id], e_cset_node[ss->id]) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 209/375 um: line: always fill *error_out in setup_one_line()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 824ac4a5edd3f7494ab1996826c4f47f8ef0f63d ]
The pointer isn't initialized by callers, but I have encountered cases where it's still printed; initialize it in all possible cases in setup_one_line().
--- arch/um/drivers/line.c | 2 ++ 1 file changed, 2 insertions(+)
arch/um/drivers/line.c +2 -0
@@ -383,6 +383,7 @@ int setup_one_line(struct line *lines, int n, char *init,parse_chan_pair (NULL , line, n, opts, error_out); err =0 ; } + *error_out ="configured as 'none'" ; }else {char *new =kstrdup (init,GFP_KERNEL );if (!new) {
@@ -406,6 +407,7 @@ int setup_one_line(struct line *lines, int n, char *init, } }if (err) { + *error_out ="failed to parse channel pair" ; line->init_str =NULL ; line->valid =0 ;kfree (new);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 210/375 devres: Initialize an uninitialized struct member
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu <[email protected]>
[ Upstream commit 56a20ad349b5c51909cf8810f7c79b288864ad33 ]
Initialize an uninitialized struct member for driver API devres_open_group().
--- drivers/base/devres.c | 1 + 1 file changed, 1 insertion(+)
drivers/base/devres.c +1 -0
@@ -567,6 +567,7 @@ void * devres_open_group(struct device *dev, void *id, gfp_t gfp) grp->id = grp;if (id) grp->id = id; + grp->color =0 ;spin_lock_irqsave (&dev->devres_lock, flags);add_dr (dev, &grp->node[0 ]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 211/375 pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krishna Kumar <[email protected]>
[ Upstream commit 335e35b748527f0c06ded9eebb65387f60647fda ]
The hotplug driver for powerpc (pci/hotplug/pnv_php.c) causes a kernel crash when we try to hot-unplug/disable the PCIe switch/bridge from the PHB.
The crash occurs because although the MSI data structure has been released during disable/hot-unplug path and it has been assigned with NULL, still during unregistration the code was again trying to explicitly disable the MSI which causes the NULL pointer dereference and kernel crash.
The patch fixes the check during unregistration path to prevent invoking pci_disable_msi/msix() since its data structure is already freed.
--- drivers/pci/hotplug/pnv_php.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/pci/hotplug/pnv_php.c +1 -2
@@ -40,7 +40,6 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, bool disable_device) {struct pci_dev *pdev = php_slot->pdev; -int irq = php_slot->irq;u16 ctrl;if (php_slot->irq >0 ) {
@@ -59,7 +58,7 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, php_slot->wq =NULL ; } -if (disable_device || irq >0 ) { +if (disable_device) {if (pdev->msix_enabled)pci_disable_msix (pdev);else if (pdev->msi_enabled)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 212/375 virtio_ring: fix KMSAN error for premapped mode
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuan Zhuo <[email protected]>
[ Upstream commit 840b2d39a2dc1b96deb3f5c7fef76c9b24f08f51 ]
Add kmsan for virtqueue_dma_map_single_attrs to fix:
BUG: KMSAN: uninit-value in receive_buf+0x45ca/0x6990 receive_buf+0x45ca/0x6990 virtnet_poll+0x17e0/0x3130 net_rx_action+0x832/0x26e0 handle_softirqs+0x330/0x10f0 [...]
Uninit was created at:
__alloc_pages_noprof+0x62a/0xe60 alloc_pages_noprof+0x392/0x830 skb_page_frag_refill+0x21a/0x5c0 virtnet_rq_alloc+0x50/0x1500 try_fill_recv+0x372/0x54c0 virtnet_open+0x210/0xbe0 __dev_open+0x56e/0x920 __dev_change_flags+0x39c/0x2000 dev_change_flags+0xaa/0x200 do_setlink+0x197a/0x7420 rtnl_setlink+0x77c/0x860 [...]
Message-Id: <[email protected]>
--- drivers/virtio/virtio_ring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/virtio/virtio_ring.c +3 -1
@@ -3121,8 +3121,10 @@ dma_addr_t virtqueue_dma_map_single_attrs(struct virtqueue *_vq, void *ptr, {struct vring_virtqueue *vq =to_vvq (_vq); -if (!vq->use_dma_api) +if (!vq->use_dma_api) { +kmsan_handle_dma (virt_to_page (ptr),offset_in_page (ptr), size, dir);return (dma_addr_t )virt_to_phys (ptr); + }return dma_map_single_attrs (vring_dma_dev (vq), ptr, size, dir, attrs); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 213/375 wifi: rtw88: usb: schedule rx work after everything is set up
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcin Ślusarz <[email protected]>
[ Upstream commit adc539784c98a7cc602cbf557debfc2e7b9be8b3 ]
Right now it's possible to hit NULL pointer dereference in rtw_rx_fill_rx_status on hw object and/or its fields because initialization routine can start getting USB replies before rtw_dev is fully setup.
The stack trace looks like this:
rtw_rx_fill_rx_statusrtw8821c_query_rx_descrtw_usb_rx_handler
...queue_workrtw_usb_read_port_complete
...usb_submit_urbrtw_usb_rx_resubmitrtw_usb_init_rxrtw_usb_probe
So while we do the async stuff rtw_usb_probe continues and calls rtw_register_hw, which does all kinds of initialization (e.g. via ieee80211_register_hw) that rtw_rx_fill_rx_status relies on.
Fix this by moving the first usb_submit_urb after everything is set up.
For me, this bug manifested as:
[ 8.893177] rtw_8821cu 1-1:1.2: band wrong, packet dropped [ 8.910904] rtw_8821cu 1-1:1.2: hw->conf.chandef.chan NULL in rtw_rx_fill_rx_status
because I'm using Larry's backport of rtw88 driver with the NULL checks in rtw_rx_fill_rx_status.
--- drivers/net/wireless/realtek/rtw88/usb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/net/wireless/realtek/rtw88/usb.c +10 -3
@@ -744,7 +744,6 @@ static struct rtw_hci_ops rtw_usb_ops = {static int rtw_usb_init_rx (struct rtw_dev *rtwdev) {struct rtw_usb *rtwusb =rtw_get_usb_priv (rtwdev); -int i; rtwusb->rxwq =create_singlethread_workqueue ("rtw88_usb: rx wq" );if (!rtwusb->rxwq) {
@@ -756,13 +755,19 @@ static int rtw_usb_init_rx(struct rtw_dev *rtwdev)INIT_WORK (&rtwusb->rx_work, rtw_usb_rx_handler); +return 0 ; +} + +static void rtw_usb_setup_rx (struct rtw_dev *rtwdev) +{ +struct rtw_usb *rtwusb =rtw_get_usb_priv (rtwdev); +int i; +for (i =0 ; i <RTW_USB_RXCB_NUM ; i++) {struct rx_usb_ctrl_block *rxcb = &rtwusb->rx_cb[i];rtw_usb_rx_resubmit (rtwusb, rxcb); } - -return 0 ; }static void rtw_usb_deinit_rx (struct rtw_dev *rtwdev)
@@ -899,6 +904,8 @@ int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err_destroy_rxwq; } +rtw_usb_setup_rx (rtwdev); +return 0 ; err_destroy_rxwq:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 214/375 scsi: ufs: core: Remove SCSI host only if added
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyoungrul Kim <[email protected]>
[ Upstream commit 7cbff570dbe8907e23bba06f6414899a0fbb2fcc ]
If host tries to remove ufshcd driver from a UFS device it would cause a kernel panic if ufshcd_async_scan fails during ufshcd_probe_hba before adding a SCSI host with scsi_add_host and MCQ is enabled since SCSI host has been defered after MCQ configuration introduced by commit 0cab4023ec7b ("scsi: ufs: core: Defer adding host to SCSI if MCQ is supported").
To guarantee that SCSI host is removed only if it has been added, set the scsi_host_added flag to true after adding a SCSI host and check whether it is set or not before removing it.
--- drivers/ufs/core/ufshcd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/ufs/core/ufshcd.c +5 -2
@@ -10196,7 +10196,8 @@ void ufshcd_remove(struct ufs_hba *hba)blk_mq_destroy_queue (hba->tmf_queue);blk_put_queue (hba->tmf_queue);blk_mq_free_tag_set (&hba->tmf_tag_set); -scsi_remove_host (hba->host); +if (hba->scsi_host_added) +scsi_remove_host (hba->host);/* disable interrupts */ ufshcd_disable_intr (hba, hba->intr_mask);ufshcd_hba_stop (hba);
@@ -10478,6 +10479,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)dev_err (hba->dev,"scsi_add_host failed\n" ); goto out_disable; } + hba->scsi_host_added = true; } hba->tmf_tag_set = (struct blk_mq_tag_set ) {
@@ -10560,7 +10562,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) free_tmf_tag_set:blk_mq_free_tag_set (&hba->tmf_tag_set); out_remove_scsi_host: -scsi_remove_host (hba->host); +if (hba->scsi_host_added) +scsi_remove_host (hba->host); out_disable: hba->is_irq_enabled = false;ufshcd_hba_exit (hba);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 215/375 scsi: pm80xx: Set phy->enable_completion only when we wait for it
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Pylypiv <[email protected]>
[ Upstream commit e4f949ef1516c0d74745ee54a0f4882c1f6c7aea ]
pm8001_phy_control() populates the enable_completion pointer with a stack address, sends a PHY_LINK_RESET / PHY_HARD_RESET, waits 300 ms, and returns. The problem arises when a phy control response comes late. After 300 ms the pm8001_phy_control() function returns and the passed enable_completion stack address is no longer valid. Late phy control response invokes complete() on a dangling enable_completion pointer which leads to a kernel crash.
--- drivers/scsi/pm8001/pm8001_sas.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/scsi/pm8001/pm8001_sas.c +3 -1
@@ -166,7 +166,6 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,unsigned long flags; pm8001_ha = sas_phy->ha->lldd_ha; phy = &pm8001_ha->phy[phy_id]; - pm8001_ha->phy[phy_id].enable_completion = &completion;if (PM8001_CHIP_DISP ->fatal_errors (pm8001_ha)) {/*
@@ -190,6 +189,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, rates->maximum_linkrate; }if (pm8001_ha->phy[phy_id].phy_state ==PHY_LINK_DISABLE ) { + pm8001_ha->phy[phy_id].enable_completion = &completion;PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, phy_id);wait_for_completion (&completion); }
@@ -198,6 +198,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,break ;case PHY_FUNC_HARD_RESET :if (pm8001_ha->phy[phy_id].phy_state ==PHY_LINK_DISABLE ) { + pm8001_ha->phy[phy_id].enable_completion = &completion;PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, phy_id);wait_for_completion (&completion); }
@@ -206,6 +207,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,break ;case PHY_FUNC_LINK_RESET :if (pm8001_ha->phy[phy_id].phy_state ==PHY_LINK_DISABLE ) { + pm8001_ha->phy[phy_id].enable_completion = &completion;PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, phy_id);wait_for_completion (&completion); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 216/375 scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Tee <[email protected]>
[ Upstream commit ede596b1434b57c0b3fd5c02b326efe5c54f6e48 ]
The MBX_TIMEOUT return code is not handled in lpfc_get_sfp_info and the routine unconditionally frees submitted mailbox commands regardless of return status. The issue is that for MBX_TIMEOUT cases, when firmware returns SFP information at a later time, that same mailbox memory region references previously freed memory in its cmpl routine.
Fix by adding checks for the MBX_TIMEOUT return code. During mailbox resource cleanup, check the mbox flag to make sure that the wait did not timeout. If the MBOX_WAKE flag is not set, then do not free the resources because it will be freed when firmware completes the mailbox at a later time in its cmpl routine.
Also, increase the timeout from 30 to 60 seconds to accommodate boot scripts requiring longer timeouts.
--- drivers/scsi/lpfc/lpfc_els.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/scsi/lpfc/lpfc_els.c +11 -6
@@ -7302,13 +7302,13 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba, mbox->u.mqe.un.mem_dump_type3.addr_hi =putPaddrHigh (mp->phys); } mbox->vport = phba->pport; - - rc =lpfc_sli_issue_mbox_wait (phba, mbox,30 ); + rc =lpfc_sli_issue_mbox_wait (phba, mbox,LPFC_MBOX_SLI4_CONFIG_TMO );if (rc ==MBX_NOT_FINISHED ) { rc =1 ; goto error; } - +if (rc ==MBX_TIMEOUT ) + goto error;if (phba->sli_rev ==LPFC_SLI_REV4 ) mp = mbox->ctx_buf;else
@@ -7361,7 +7361,10 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba, mbox->u.mqe.un.mem_dump_type3.addr_hi =putPaddrHigh (mp->phys); } - rc =lpfc_sli_issue_mbox_wait (phba, mbox,30 ); + rc =lpfc_sli_issue_mbox_wait (phba, mbox,LPFC_MBOX_SLI4_CONFIG_TMO ); + +if (rc ==MBX_TIMEOUT ) + goto error;if (bf_get (lpfc_mqe_status, &mbox->u.mqe)) { rc =1 ; goto error;
@@ -7372,8 +7375,10 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba, DMP_SFF_PAGE_A2_SIZE); error: - mbox->ctx_buf = mpsave; -lpfc_mbox_rsrc_cleanup (phba, mbox,MBOX_THD_UNLOCKED ); +if (mbox->mbox_flag &LPFC_MBX_WAKE ) { + mbox->ctx_buf = mpsave; +lpfc_mbox_rsrc_cleanup (phba, mbox,MBOX_THD_UNLOCKED ); + }return rc;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 217/375 crypto: qat - fix unintentional re-enabling of error interrupts
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hareshx Sankar Raj <[email protected]>
[ Upstream commit f0622894c59458fceb33c4197462bc2006f3fc6b ]
The logic that detects pending VF2PF interrupts unintentionally clears the section of the error mask register(s) not related to VF2PF. This might cause interrupts unrelated to VF2PF, reported through errsou3 and errsou5, to be reported again after the execution of the function disable_pending_vf2pf_interrupts() in dh895xcc and GEN2 devices.
Fix by updating only section of errmsk3 and errmsk5 related to VF2PF.
--- drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c | 4 +++- .../crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-)
drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c +3 -1
@@ -100,7 +100,9 @@ static u32 adf_gen2_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr) errmsk3 |=ADF_GEN2_ERR_MSK_VF2PF (ADF_GEN2_VF_MSK );ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK3 , errmsk3); - errmsk3 &=ADF_GEN2_ERR_MSK_VF2PF (sources | disabled); +/* Update only section of errmsk3 related to VF2PF */ + errmsk3 &= ~ADF_GEN2_ERR_MSK_VF2PF (ADF_GEN2_VF_MSK ); + errmsk3 |=ADF_GEN2_ERR_MSK_VF2PF (sources | disabled);ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK3 , errmsk3);/* Return the sources of the (new) interrupt(s) */
drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +6 -2
@@ -193,8 +193,12 @@ static u32 disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK3 , errmsk3);ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK5 , errmsk5); - errmsk3 &=ADF_DH895XCC_ERR_MSK_VF2PF_L (sources | disabled); - errmsk5 &=ADF_DH895XCC_ERR_MSK_VF2PF_U (sources | disabled); +/* Update only section of errmsk3 and errmsk5 related to VF2PF */ + errmsk3 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_L (ADF_DH895XCC_VF_MSK ); + errmsk5 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_U (ADF_DH895XCC_VF_MSK ); + + errmsk3 |=ADF_DH895XCC_ERR_MSK_VF2PF_L (sources | disabled); + errmsk5 |=ADF_DH895XCC_ERR_MSK_VF2PF_U (sources | disabled);ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK3 , errmsk3);ADF_CSR_WR (pmisc_addr,ADF_GEN2_ERRMSK5 , errmsk5);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 218/375 tracing/kprobes: Add symbol counting check when module loads
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <[email protected]>
[ Upstream commit 9d8616034f161222a4ac166c1b42b6d79961c005 ]
Currently, kprobe event checks whether the target symbol name is unique or not, so that it does not put a probe on an unexpected place. But this skips the check if the target is on a module because the module may not be loaded.
To fix this issue, this patch checks the number of probe target symbols in a target module when the module is loaded. If the probe is not on the unique name symbols in the module, it will be rejected at that point.
Note that the symbol which has a unique name in the target module, it will be accepted even if there are same-name symbols in the kernel or other modules,
--- kernel/trace/trace_kprobe.c | 125 +++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 44 deletions(-)
kernel/trace/trace_kprobe.c +81 -44
@@ -678,6 +678,21 @@ static int register_trace_kprobe(struct trace_kprobe *tk) }#ifdef CONFIG_MODULES +static int validate_module_probe_symbol (const char *modname,const char *symbol); + +static int register_module_trace_kprobe (struct module *mod,struct trace_kprobe *tk) +{ +const char *p; +int ret =0 ; + + p =strchr (trace_kprobe_symbol (tk),':' ); +if (p) + ret =validate_module_probe_symbol (module_name (mod), p +1 ); +if (!ret) + ret =__register_trace_kprobe (tk); +return ret; +} +/* Module notifier call back, checking event on the module */ static int trace_kprobe_module_callback (struct notifier_block *nb,unsigned long val,void *data)
@@ -696,7 +711,7 @@ static int trace_kprobe_module_callback(struct notifier_block *nb,if (trace_kprobe_within_module (tk, mod)) {/* Don't need to check busy - this should have gone. */ __unregister_trace_kprobe (tk); - ret =__register_trace_kprobe (tk); + ret =register_module_trace_kprobe (mod, tk);if (ret) pr_warn("Failed to re-register probe %s on %s: %d\n", trace_probe_name(&tk->tp),
@@ -747,17 +762,68 @@ static int count_mod_symbols(void *data, const char *name, unsigned long unused)return 0 ; } -static unsigned int number_of_same_symbols (char *func_name) +static unsigned int number_of_same_symbols (const char *mod,const char *func_name) {struct sym_count_ctx ctx = { .count =0 , .name = func_name }; -kallsyms_on_each_match_symbol (count_symbols, func_name, &ctx.count); +if (!mod) +kallsyms_on_each_match_symbol (count_symbols, func_name, &ctx.count); -module_kallsyms_on_each_symbol (NULL , count_mod_symbols, &ctx); +module_kallsyms_on_each_symbol (mod, count_mod_symbols, &ctx);return ctx.count; } +static int validate_module_probe_symbol (const char *modname,const char *symbol) +{ +unsigned int count =number_of_same_symbols (modname, symbol); + +if (count >1 ) { +/* +* Users should use ADDR to remove the ambiguity of +* using KSYM only. +*/ +return -EADDRNOTAVAIL ; + }else if (count ==0 ) { +/* +* We can return ENOENT earlier than when register the +* kprobe. +*/ +return -ENOENT ; + } +return 0 ; +} + +static int validate_probe_symbol (char *symbol) +{ +struct module *mod =NULL ; +char *modname =NULL , *p; +int ret =0 ; + + p =strchr (symbol,':' ); +if (p) { + modname = symbol; + symbol = p +1 ; + *p ='\0' ; +/* Return 0 (defer) if the module does not exist yet. */ +rcu_read_lock_sched (); + mod =find_module (modname); +if (mod && !try_module_get (mod)) + mod =NULL ; +rcu_read_unlock_sched (); +if (!mod) + goto out; + } + + ret =validate_module_probe_symbol (modname, symbol); +out: +if (p) + *p =':' ; +if (mod) +module_put (mod); +return ret; +} +static int trace_kprobe_entry_handler (struct kretprobe_instance *ri,struct pt_regs *regs);
@@ -881,6 +947,14 @@ static int __trace_kprobe_create(int argc, const char *argv[])trace_probe_log_err (0 ,BAD_PROBE_ADDR ); goto parse_error; } + ret =validate_probe_symbol (symbol); +if (ret) { +if (ret == -EADDRNOTAVAIL ) +trace_probe_log_err (0 ,NON_UNIQ_SYMBOL ); +else +trace_probe_log_err (0 ,BAD_PROBE_ADDR ); + goto parse_error; + }if (is_return) ctx.flags |=TPARG_FL_RETURN ; ret =kprobe_on_func_entry (NULL , symbol, offset);
@@ -893,31 +967,6 @@ static int __trace_kprobe_create(int argc, const char *argv[]) } } -if (symbol && !strchr (symbol,':' )) { -unsigned int count; - - count =number_of_same_symbols (symbol); -if (count >1 ) { -/* -* Users should use ADDR to remove the ambiguity of -* using KSYM only. -*/ -trace_probe_log_err (0 ,NON_UNIQ_SYMBOL ); - ret = -EADDRNOTAVAIL ; - - goto error; - }else if (count ==0 ) { -/* -* We can return ENOENT earlier than when register the -* kprobe. -*/ -trace_probe_log_err (0 ,BAD_PROBE_ADDR ); - ret = -ENOENT ; - - goto error; - } - } -trace_probe_log_set_index (0 );if (event) { ret = traceprobe_parse_event_name(&event, &group, gbuf,
@@ -1835,21 +1884,9 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,char *event;if (func) { -unsigned int count; - - count =number_of_same_symbols (func); -if (count >1 ) -/* -* Users should use addr to remove the ambiguity of -* using func only. -*/ -return ERR_PTR (-EADDRNOTAVAIL ); -else if (count ==0 ) -/* -* We can return ENOENT earlier than when register the -* kprobe. -*/ -return ERR_PTR (-ENOENT ); + ret =validate_probe_symbol (func); +if (ret) +return ERR_PTR (ret); }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 219/375 hwmon: (adc128d818) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 8cad724c8537fe3e0da8004646abc00290adae40 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/adc128d818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/adc128d818.c +2 -2
@@ -175,7 +175,7 @@ static ssize_t adc128_in_store(struct device *dev,mutex_lock (&data->update_lock);/* 10 mV LSB on limit registers */ - regval =clamp_val (DIV_ROUND_CLOSEST (val,10 ),0 ,255 ); + regval =DIV_ROUND_CLOSEST (clamp_val (val,0 ,2550 ),10 ); data->in[index][nr] = regval <<4 ; reg = index ==1 ?ADC128_REG_IN_MIN (nr) :ADC128_REG_IN_MAX (nr);i2c_smbus_write_byte_data (data->client, reg, regval);
@@ -213,7 +213,7 @@ static ssize_t adc128_temp_store(struct device *dev,return err;mutex_lock (&data->update_lock); - regval =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),-128 ,127 ); + regval =DIV_ROUND_CLOSEST (clamp_val (val,-128000 ,127000 ),1000 ); data->temp[index] = regval <<1 ; i2c_smbus_write_byte_data(data->client, index == 1 ? ADC128_REG_TEMP_MAX
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 220/375 hwmon: (lm95234) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit af64e3e1537896337405f880c1e9ac1f8c0c6198 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/lm95234.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/hwmon/lm95234.c +5 -4
@@ -301,7 +301,8 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr,if (ret <0 )return ret; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 , index ?255 :127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 , (index ?255 :127 ) *1000 ), +1000 );mutex_lock (&data->update_lock); data->tcrit2[index] = val;
@@ -350,7 +351,7 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr,if (ret <0 )return ret; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,255 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,255000 ),1000 );mutex_lock (&data->update_lock); data->tcrit1[index] = val;
@@ -391,7 +392,7 @@ static ssize_t tcrit1_hyst_store(struct device *dev,if (ret <0 )return ret; - val =DIV_ROUND_CLOSEST (val,1000 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-255000 ,255000 ),1000 ); val =clamp_val ((int )data->tcrit1[index] - val,0 ,31 );mutex_lock (&data->update_lock);
@@ -431,7 +432,7 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr,return ret;/* Accuracy is 1/2 degrees C */ - val =clamp_val (DIV_ROUND_CLOSEST (val,500 ),-128 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-64000 ,63500 ),500 );mutex_lock (&data->update_lock); data->toffset[index] = val;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 221/375 hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 0403e10bf0824bf0ec2bb135d4cf1c0cc3bf4bf0 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/nct6775-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/nct6775-core.c +1 -1
@@ -2262,7 +2262,7 @@ store_temp_offset(struct device *dev, struct device_attribute *attr,if (err <0 )return err; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),-128 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,-128000 ,127000 ),1000 );mutex_lock (&data->update_lock); data->temp_offset[nr] = val;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 222/375 hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 5c1de37969b7bc0abcb20b86e91e70caebbd4f89 ]
DIV_ROUND_CLOSEST() after kstrtol() results in an underflow if a large negative number such as -9223372036854775808 is provided by the user. Fix it by reordering clamp_val() and DIV_ROUND_CLOSEST() operations.
--- drivers/hwmon/w83627ehf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/w83627ehf.c +2 -2
@@ -895,7 +895,7 @@ store_target_temp(struct device *dev, struct device_attribute *attr,if (err <0 )return err; - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,127 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,127000 ),1000 );mutex_lock (&data->update_lock); data->target_temp[nr] = val;
@@ -920,7 +920,7 @@ store_tolerance(struct device *dev, struct device_attribute *attr,return err;/* Limit the temp to 0C - 15C */ - val =clamp_val (DIV_ROUND_CLOSEST (val,1000 ),0 ,15 ); + val =DIV_ROUND_CLOSEST (clamp_val (val,0 ,15000 ),1000 );mutex_lock (&data->update_lock); reg =w83627ehf_read_value (data,W83627EHF_REG_TOLERANCE [nr]);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 223/375 ASoc: TAS2781: replace beXX_to_cpup with get_unaligned_beXX for potentially broken alignment
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shenghao Ding <[email protected]>
[ Upstream commit 1cc509edbe23b61e8c245611bd15d88edb635a38 ]
Use get_unaligned_be16 instead of be16_to_cpup and get_unaligned_be32 instead of be32_to_cpup for potentially broken alignment.
--- sound/soc/codecs/tas2781-fmwlib.c | 71 +++++++++++++++---------------- 1 file changed, 35 insertions(+), 36 deletions(-)
sound/soc/codecs/tas2781-fmwlib.c +35 -36
@@ -21,7 +21,7 @@#include <sound/soc.h> #include <sound/tlv.h> #include <sound/tas2781.h> - +#include <asm/unaligned.h> #define ERROR_PRAM_CRCCHK 0x0000000#define ERROR_YRAM_CRCCHK 0x0000001
@@ -187,8 +187,7 @@ static struct tasdevice_config_info *tasdevice_add_config(/* convert data[offset], data[offset + 1], data[offset + 2] and * data[offset + 3] into host */ - cfg_info->nblocks = -be32_to_cpup ((__be32 *)&config_data[config_offset]); + cfg_info->nblocks =get_unaligned_be32 (&config_data[config_offset]); config_offset +=4 ;/* Several kinds of dsp/algorithm firmwares can run on tas2781,
@@ -232,14 +231,14 @@ static struct tasdevice_config_info *tasdevice_add_config( } bk_da[i]->yram_checksum = -be16_to_cpup ((__be16 *)&config_data[config_offset]); +get_unaligned_be16 (&config_data[config_offset]); config_offset +=2 ; bk_da[i]->block_size = -be32_to_cpup ((__be32 *)&config_data[config_offset]); +get_unaligned_be32 (&config_data[config_offset]); config_offset +=4 ; bk_da[i]->n_subblks = -be32_to_cpup ((__be32 *)&config_data[config_offset]); +get_unaligned_be32 (&config_data[config_offset]); config_offset +=4 ;
@@ -289,7 +288,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) } buf = (unsigned char *)fmw->data; - fw_hdr->img_sz =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->img_sz =get_unaligned_be32 (&buf[offset]); offset +=4 ;if (fw_hdr->img_sz != fmw->size) { dev_err(tas_priv->dev,
@@ -300,9 +299,9 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) goto out; } - fw_hdr->checksum =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->checksum =get_unaligned_be32 (&buf[offset]); offset +=4 ; - fw_hdr->binary_version_num =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->binary_version_num =get_unaligned_be32 (&buf[offset]);if (fw_hdr->binary_version_num <0x103 ) {dev_err (tas_priv->dev,"File version 0x%04x is too low" , fw_hdr->binary_version_num);
@@ -311,7 +310,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) goto out; } offset +=4 ; - fw_hdr->drv_fw_version =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->drv_fw_version =get_unaligned_be32 (&buf[offset]); offset +=8 ; fw_hdr->plat_type = buf[offset]; offset +=1 ;
@@ -339,11 +338,11 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)for (i =0 ; i <TASDEVICE_DEVICE_SUM ; i++, offset++) fw_hdr->devs[i] = buf[offset]; - fw_hdr->nconfig =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->nconfig =get_unaligned_be32 (&buf[offset]); offset +=4 ;for (i =0 ; i <TASDEVICE_CONFIG_SUM ; i++) { - fw_hdr->config_size[i] =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->config_size[i] =get_unaligned_be32 (&buf[offset]); offset +=4 ; total_config_sz += fw_hdr->config_size[i]; }
@@ -423,7 +422,7 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,/* convert data[offset], data[offset + 1], data[offset + 2] and * data[offset + 3] into host */ - block->type =be32_to_cpup ((__be32 *)&data[offset]); + block->type =get_unaligned_be32 (&data[offset]); offset +=4 ; block->is_pchksum_present = data[offset];
@@ -438,10 +437,10 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw, block->ychksum = data[offset]; offset++; - block->blk_size =be32_to_cpup ((__be32 *)&data[offset]); + block->blk_size =get_unaligned_be32 (&data[offset]); offset +=4 ; - block->nr_subblocks =be32_to_cpup ((__be32 *)&data[offset]); + block->nr_subblocks =get_unaligned_be32 (&data[offset]); offset +=4 ;/* fixed m68k compiling issue:
@@ -482,7 +481,7 @@ static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw, offset = -EINVAL ; goto out; } - img_data->nr_blk =be32_to_cpup ((__be32 *)&data[offset]); + img_data->nr_blk =get_unaligned_be32 (&data[offset]); offset +=4 ; img_data->dev_blks = kcalloc(img_data->nr_blk,
@@ -578,14 +577,14 @@ static int fw_parse_variable_header_kernel( offset = -EINVAL ; goto out; } - fw_hdr->device_family =be16_to_cpup ((__be16 *)&buf[offset]); + fw_hdr->device_family =get_unaligned_be16 (&buf[offset]);if (fw_hdr->device_family !=0 ) {dev_err (tas_priv->dev,"%s:not TAS device\n" , __func__); offset = -EINVAL ; goto out; } offset +=2 ; - fw_hdr->device =be16_to_cpup ((__be16 *)&buf[offset]); + fw_hdr->device =get_unaligned_be16 (&buf[offset]);if (fw_hdr->device >=TASDEVICE_DSP_TAS_MAX_DEVICE || fw_hdr->device ==6 ) {dev_err (tas_priv->dev,"Unsupported dev %d\n" , fw_hdr->device);
@@ -603,7 +602,7 @@ static int fw_parse_variable_header_kernel( goto out; } - tas_fmw->nr_programs =be32_to_cpup ((__be32 *)&buf[offset]); + tas_fmw->nr_programs =get_unaligned_be32 (&buf[offset]); offset +=4 ; if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs >
@@ -622,14 +621,14 @@ static int fw_parse_variable_header_kernel(for (i =0 ; i < tas_fmw->nr_programs; i++) { program = &(tas_fmw->programs[i]); - program->prog_size =be32_to_cpup ((__be32 *)&buf[offset]); + program->prog_size =get_unaligned_be32 (&buf[offset]); offset +=4 ; }/* Skip the unused prog_size */ offset +=4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs); - tas_fmw->nr_configurations =be32_to_cpup ((__be32 *)&buf[offset]); + tas_fmw->nr_configurations =get_unaligned_be32 (&buf[offset]); offset +=4 ;/* The max number of config in firmware greater than 4 pieces of
@@ -661,7 +660,7 @@ static int fw_parse_variable_header_kernel(for (i =0 ; i < tas_fmw->nr_programs; i++) { config = &(tas_fmw->configs[i]); - config->cfg_size =be32_to_cpup ((__be32 *)&buf[offset]); + config->cfg_size =get_unaligned_be32 (&buf[offset]); offset +=4 ; }
@@ -699,7 +698,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,switch (subblk_typ) {case TASDEVICE_CMD_SING_W : {int i; -unsigned short len =be16_to_cpup ((__be16 *)&data[2 ]); +unsigned short len =get_unaligned_be16 (&data[2 ]); subblk_offset +=2 ;if (subblk_offset +4 * len > sublocksize) {
@@ -725,7 +724,7 @@ static int tasdevice_process_block(void *context, unsigned char *data, }break ;case TASDEVICE_CMD_BURST : { -unsigned short len =be16_to_cpup ((__be16 *)&data[2 ]); +unsigned short len =get_unaligned_be16 (&data[2 ]); subblk_offset +=2 ;if (subblk_offset +4 + len > sublocksize) {
@@ -766,7 +765,7 @@ static int tasdevice_process_block(void *context, unsigned char *data, is_err = true;break ; } - sleep_time =be16_to_cpup ((__be16 *)&data[2 ]) *1000 ; + sleep_time =get_unaligned_be16 (&data[2 ]) *1000 ;usleep_range (sleep_time, sleep_time +50 ); subblk_offset +=2 ; }
@@ -910,7 +909,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv offset += len; - fw_hdr->device_family =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->device_family =get_unaligned_be32 (&buf[offset]);if (fw_hdr->device_family !=0 ) {dev_err (tas_priv->dev,"%s: not TAS device\n" , __func__); offset = -EINVAL ;
@@ -918,7 +917,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv } offset +=4 ; - fw_hdr->device =be32_to_cpup ((__be32 *)&buf[offset]); + fw_hdr->device =get_unaligned_be32 (&buf[offset]);if (fw_hdr->device >=TASDEVICE_DSP_TAS_MAX_DEVICE || fw_hdr->device ==6 ) {dev_err (tas_priv->dev,"Unsupported dev %d\n" , fw_hdr->device);
@@ -963,7 +962,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw, offset = -EINVAL ; goto out; } - block->type =be32_to_cpup ((__be32 *)&data[offset]); + block->type =get_unaligned_be32 (&data[offset]); offset +=4 ;if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >=PPC_DRIVER_CRCCHK ) {
@@ -988,7 +987,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw, block->is_ychksum_present =0 ; } - block->nr_cmds =be32_to_cpup ((__be32 *)&data[offset]); + block->nr_cmds =get_unaligned_be32 (&data[offset]); offset +=4 ; n = block->nr_cmds *4 ;
@@ -1039,7 +1038,7 @@ static int fw_parse_data(struct tasdevice_fw *tas_fmw, goto out; } offset += n; - img_data->nr_blk =be16_to_cpup ((__be16 *)&data[offset]); + img_data->nr_blk =get_unaligned_be16 (&data[offset]); offset +=2 ; img_data->dev_blks = kcalloc(img_data->nr_blk,
@@ -1076,7 +1075,7 @@ static int fw_parse_program_data(struct tasdevice_priv *tas_priv, offset = -EINVAL ; goto out; } - tas_fmw->nr_programs =be16_to_cpup ((__be16 *)&buf[offset]); + tas_fmw->nr_programs =get_unaligned_be16 (&buf[offset]); offset +=2 ;if (tas_fmw->nr_programs ==0 ) {
@@ -1143,7 +1142,7 @@ static int fw_parse_configuration_data( offset = -EINVAL ; goto out; } - tas_fmw->nr_configurations =be16_to_cpup ((__be16 *)&data[offset]); + tas_fmw->nr_configurations =get_unaligned_be16 (&data[offset]); offset +=2 ;if (tas_fmw->nr_configurations ==0 ) {
@@ -1775,7 +1774,7 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv,/* Convert data[offset], data[offset + 1], data[offset + 2] and * data[offset + 3] into host */ - fw_fixed_hdr->fwsize =be32_to_cpup ((__be32 *)&buf[offset]); + fw_fixed_hdr->fwsize =get_unaligned_be32 (&buf[offset]); offset +=4 ;if (fw_fixed_hdr->fwsize != fmw->size) { dev_err(tas_priv->dev, "File size not match, %lu %u",
@@ -1784,9 +1783,9 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv, goto out; } offset +=4 ; - fw_fixed_hdr->ppcver =be32_to_cpup ((__be32 *)&buf[offset]); + fw_fixed_hdr->ppcver =get_unaligned_be32 (&buf[offset]); offset +=8 ; - fw_fixed_hdr->drv_ver =be32_to_cpup ((__be32 *)&buf[offset]); + fw_fixed_hdr->drv_ver =get_unaligned_be32 (&buf[offset]); offset +=72 ; out:
@@ -1828,7 +1827,7 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv, offset = -EINVAL ; goto out; } - tas_fmw->nr_calibrations =be16_to_cpup ((__be16 *)&data[offset]); + tas_fmw->nr_calibrations =get_unaligned_be16 (&data[offset]); offset +=2 ;if (tas_fmw->nr_calibrations !=1 ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 224/375 libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andreas Ziegler <[email protected]>
[ Upstream commit cedc12c5b57f7efa6dbebfb2b140e8675f5a2616 ]
In the current state, an erroneous call to bpf_object__find_map_by_name(NULL, ...) leads to a segmentation fault through the following call chain:
bpf_object__find_map_by_name(obj = NULL, ...)
-> bpf_object__for_each_map(pos, obj = NULL)
-> bpf_object__next_map((obj = NULL), NULL)
-> return (obj = NULL)->maps
While calling bpf_object__find_map_by_name with obj = NULL is obviously incorrect, this should not lead to a segmentation fault but rather be handled gracefully.
As __bpf_map__iter already handles this situation correctly, we can delegate the check for the regular case there and only add a check in case the prev or next parameter is NULL.
--- tools/lib/bpf/libbpf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/lib/bpf/libbpf.c +2 -2
@@ -10336,7 +10336,7 @@ __bpf_map__iter(const struct bpf_map *m, const struct bpf_object *obj, int i)struct bpf_map *bpf_object__next_map (const struct bpf_object *obj,const struct bpf_map *prev) { -if (prev ==NULL ) +if (prev ==NULL && obj !=NULL )return obj->maps;return __bpf_map__iter (prev, obj,1 );
@@ -10345,7 +10345,7 @@ bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *prev)struct bpf_map *bpf_object__prev_map (const struct bpf_object *obj,const struct bpf_map *next) { -if (next ==NULL ) { +if (next ==NULL && obj !=NULL ) {if (!obj->nr_maps)return NULL ;return obj->maps + obj->nr_maps -1 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 225/375 drm/amdgpu: Set no_hw_access when VF request full GPU fails
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifan Zha <[email protected]>
[ Upstream commit 33f23fc3155b13c4a96d94a0a22dc26db767440b ]
[Why]
If VF request full GPU access and the request failed,
the VF driver can get stuck accessing registers for an extended period during the unload of KMS.
[How]
Set no_hw_access flag when VF request for full GPU access fails This prevents further hardware access attempts, avoiding the prolonged stuck state.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +3 -1
@@ -86,8 +86,10 @@ int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init)if (virt->ops && virt->ops->req_full_gpu) { r = virt->ops->req_full_gpu (adev, init); -if (r) +if (r) { + adev->no_hw_access = true;return r; + } adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 226/375 ext4: fix possible tid_t sequence overflows
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Henriques (SUSE) <[email protected]>
[ Upstream commit 63469662cc45d41705f14b4648481d5d29cf5999 ]
In the fast commit code there are a few places where tid_t variables are being compared without taking into account the fact that these sequence numbers may wrap. Fix this issue by using the helper functions tid_gt() and tid_geq().
--- fs/ext4/fast_commit.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/ext4/fast_commit.c +4 -4
@@ -353,7 +353,7 @@ void ext4_fc_mark_ineligible(struct super_block *sb, int reason, handle_t *handlread_unlock (&sbi->s_journal->j_state_lock); }spin_lock (&sbi->s_fc_lock); -if (sbi->s_fc_ineligible_tid < tid) +if (tid_gt (tid, sbi->s_fc_ineligible_tid)) sbi->s_fc_ineligible_tid = tid;spin_unlock (&sbi->s_fc_lock);WARN_ON (reason >=EXT4_FC_REASON_MAX );
@@ -1213,7 +1213,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid)if (ret == -EALREADY ) {/* There was an ongoing commit, check if we need to restart */ if (atomic_read (&sbi->s_fc_subtid) <= subtid && - commit_tid > journal->j_commit_sequence) +tid_gt (commit_tid, journal->j_commit_sequence)) goto restart_fc;ext4_fc_update_stats (sb,EXT4_FC_STATUS_SKIPPED ,0 ,0 , commit_tid);
@@ -1288,7 +1288,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)list_del_init (&iter->i_fc_list);ext4_clear_inode_state (&iter->vfs_inode,EXT4_STATE_FC_COMMITTING ); -if (iter->i_sync_tid <= tid) +if (tid_geq (tid, iter->i_sync_tid))ext4_fc_reset_inode (&iter->vfs_inode);/* Make sure EXT4_STATE_FC_COMMITTING bit is clear */ smp_mb ();
@@ -1319,7 +1319,7 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)list_splice_init (&sbi->s_fc_q[FC_Q_STAGING ], &sbi->s_fc_q[FC_Q_MAIN ]); -if (tid >= sbi->s_fc_ineligible_tid) { +if (tid_geq (tid, sbi->s_fc_ineligible_tid)) { sbi->s_fc_ineligible_tid =0 ;ext4_clear_mount_flag (sb,EXT4_MF_FC_INELIGIBLE ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 227/375 jbd2: avoid mount failed when commit block is partial submitted
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 0bab8db4152c4a2185a1367db09cc402bdc62d5e ]
We encountered a problem that the file system could not be mounted in the power-off scenario. The analysis of the file system mirror shows that only part of the data is written to the last commit block.
The valid data of the commit block is concentrated in the first sector. However, the data of the entire block is involved in the checksum calculation. For different hardware, the minimum atomic unit may be different. If the checksum of a committed block is incorrect, clear the data except the 'commit_header' and then calculate the checksum. If the checkusm is correct, it is considered that the block is partially committed, Then continue to replay journal.
--- fs/jbd2/recovery.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
fs/jbd2/recovery.c +30 -0
@@ -443,6 +443,27 @@ static int jbd2_commit_block_csum_verify(journal_t *j, void *buf)return provided ==cpu_to_be32 (calculated); } +static bool jbd2_commit_block_csum_verify_partial (journal_t *j,void *buf) +{ +struct commit_header *h; +__be32 provided; +__u32 calculated; +void *tmpbuf; + + tmpbuf =kzalloc (j->j_blocksize,GFP_KERNEL ); +if (!tmpbuf) +return false; + +memcpy (tmpbuf, buf,sizeof (struct commit_header )); + h = tmpbuf; + provided = h->h_chksum[0 ]; + h->h_chksum[0 ] =0 ; + calculated =jbd2_chksum (j, j->j_csum_seed, tmpbuf, j->j_blocksize); +kfree (tmpbuf); + +return provided ==cpu_to_be32 (calculated); +} +static int jbd2_block_tag_csum_verify (journal_t *j,journal_block_tag_t *tag,journal_block_tag3_t *tag3,void *buf,__u32 sequence)
@@ -810,6 +831,13 @@ static int do_one_pass(journal_t *journal,if (pass ==PASS_SCAN && !jbd2_commit_block_csum_verify (journal, bh->b_data)) { +if (jbd2_commit_block_csum_verify_partial ( + journal, + bh->b_data)) { +pr_notice ("JBD2: Find incomplete commit block in transaction %u block %lu\n" , + next_commit_ID, next_log_block); + goto chksum_ok; + } chksum_error:if (commit_time < last_trans_commit_time) goto ignore_crc_mismatch;
@@ -824,6 +852,7 @@ static int do_one_pass(journal_t *journal, } }if (pass ==PASS_SCAN ) { + chksum_ok: last_trans_commit_time = commit_time; head_block = next_log_block; }
@@ -843,6 +872,7 @@ static int do_one_pass(journal_t *journal, next_log_block); need_check_commit_time = true; } +/* If we aren't in the REVOKE pass, then we can * just skip over this block. */ if (pass !=PASS_REVOKE ) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 228/375 dma-mapping: benchmark: Dont starve others when doing the test
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yicong Yang <[email protected]>
[ Upstream commit 54624acf8843375a6de3717ac18df3b5104c39c5 ]
The test thread will start N benchmark kthreads and then schedule out until the test time finished and notify the benchmark kthreads to stop. The benchmark kthreads will keep running until notified to stop. There's a problem with current implementation when the benchmark kthreads number is equal to the CPUs on a non-preemptible kernel:
since the scheduler will balance the kthreads across the CPUs and when the test time's out the test thread won't get a chance to be scheduled on any CPU then cannot notify the benchmark kthreads to stop.
This can be easily reproduced on a VM (simulated with 16 CPUs) with PREEMPT_VOLUNTARY:
estuary:/mnt$ ./dma_map_benchmark -t 16 -s 1 rcu: INFO: rcu_sched self-detected stall on CPU rcu: 10-...!: (5221 ticks this GP) idle=ed24/1/0x4000000000000000 softirq=142/142 fqs=0 rcu: (t=5254 jiffies g=-559 q=45 ncpus=16) rcu: rcu_sched kthread starved for 5255 jiffies! g-559 f0x0 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=12 rcu: Unless rcu_sched kthread gets sufficient CPU time, OOM is now expected behavior. rcu: RCU grace-period kthread stack dump: task:rcu_sched state:R running task stack:0 pid:16 tgid:16 ppid:2 flags:0x00000008 Call trace __switch_to+0xec/0x138 __schedule+0x2f8/0x1080 schedule+0x30/0x130 schedule_timeout+0xa0/0x188 rcu_gp_fqs_loop+0x128/0x528 rcu_gp_kthread+0x1c8/0x208 kthread+0xec/0xf8 ret_from_fork+0x10/0x20 Sending NMI from CPU 10 to CPUs 0: NMI backtrace for cpu 0 CPU: 0 PID: 332 Comm: dma-map-benchma Not tainted 6.10.0-rc1-vanilla-LSE #8 Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : arm_smmu_cmdq_issue_cmdlist+0x218/0x730 lr : arm_smmu_cmdq_issue_cmdlist+0x488/0x730 sp : ffff80008748b630 x29: ffff80008748b630 x28: 0000000000000000 x27: ffff80008748b780 x26: 0000000000000000 x25: 000000000000bc70 x24: 000000000001bc70 x23: ffff0000c12af080 x22: 0000000000010000 x21: 000000000000ffff x20: ffff80008748b700 x19: ffff0000c12af0c0 x18: 0000000000010000 x17: 0000000000000001 x16: 0000000000000040 x15: ffffffffffffffff x14: 0001ffffffffffff x13: 000000000000ffff x12: 00000000000002f1 x11: 000000000001ffff x10: 0000000000000031 x9 : ffff800080b6b0b8 x8 : ffff0000c2a48000 x7 : 000000000001bc71 x6 : 0001800000000000 x5 : 00000000000002f1 x4 : 01ffffffffffffff x3 : 000000000009aaf1 x2 : 0000000000000018 x1 : 000000000000000f x0 : ffff0000c12af18c Call trace: arm_smmu_cmdq_issue_cmdlist+0x218/0x730 __arm_smmu_tlb_inv_range+0xe0/0x1a8 arm_smmu_iotlb_sync+0xc0/0x128 __iommu_dma_unmap+0x248/0x320 iommu_dma_unmap_page+0x5c/0xe8 dma_unmap_page_attrs+0x38/0x1d0 map_benchmark_thread+0x118/0x2c0 kthread+0xec/0xf8 ret_from_fork+0x10/0x20
Solve this by adding scheduling point in the kthread loop, so if there're other threads in the system they may have a chance to run, especially the thread to notify the test end. However this may degrade the test concurrency so it's recommended to run this on an idle system.
--- kernel/dma/map_benchmark.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
kernel/dma/map_benchmark.c +16 -0
@@ -89,6 +89,22 @@ static int map_benchmark_thread(void *data)atomic64_add (map_sq, &map->sum_sq_map);atomic64_add (unmap_sq, &map->sum_sq_unmap);atomic64_inc (&map->loops); + +/* +* We may test for a long time so periodically check whether +* we need to schedule to avoid starving the others. Otherwise +* we may hangup the kernel in a non-preemptible kernel when +* the test kthreads number >= CPU number, the test kthreads +* will run endless on every CPU since the thread resposible +* for notifying the kthread stop (in do_map_benchmark()) +* could not be scheduled. +* +* Note this may degrade the test concurrency since the test +* threads may need to share the CPU time with other load +* in the system. So it's recommended to run this benchmark +* on an idle system. +*/ +cond_resched (); } out:
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 229/375 wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
[ Upstream commit c145eea2f75ff7949392aebecf7ef0a81c1f6c14 ]
mwifiex_get_priv_by_id() returns the priv pointer corresponding to the bss_num and bss_type, but without checking if the priv is actually currently in use.
Unused priv pointers do not have a wiphy attached to them which can lead to NULL pointer dereferences further down the callstack. Fix this by returning only used priv pointers which have priv->bss_mode set to something else than NL80211_IFTYPE_UNSPECIFIED.
Said NULL pointer dereference happened when an Accesspoint was started with wpa_supplicant -i mlan0 with this config:
network={
ssid="somessid"
mode=2
frequency=2412
key_mgmt=WPA-PSK WPA-PSK-SHA256
proto=RSN
group=CCMP
pairwise=CCMP
psk="12345678"
}When waiting for the AP to be established, interrupting wpa_supplicant with <ctrl-c> and starting it again this happens:
| Unable to handle kernel NULL pointer dereference at virtual address 0000000000000140 | Mem abort info: | ESR = 0x0000000096000004 | EC = 0x25: DABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x04: level 0 translation fault | Data abort info: | ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 | CM = 0, WnR = 0, TnD = 0, TagAccess = 0 | GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 | user pgtable: 4k pages, 48-bit VAs, pgdp=0000000046d96000 | [0000000000000140] pgd=0000000000000000, p4d=0000000000000000 | Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP | Modules linked in: caam_jr caamhash_desc spidev caamalg_desc crypto_engine authenc libdes mwifiex_sdio +mwifiex crct10dif_ce cdc_acm onboard_usb_hub fsl_imx8_ddr_perf imx8m_ddrc rtc_ds1307 lm75 rtc_snvs +imx_sdma caam imx8mm_thermal spi_imx error imx_cpufreq_dt fuse ip_tables x_tables ipv6 | CPU: 0 PID: 8 Comm: kworker/0:1 Not tainted 6.9.0-00007-g937242013fce-dirty #18 | Hardware name: somemachine (DT) | Workqueue: events sdio_irq_work | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : mwifiex_get_cfp+0xd8/0x15c [mwifiex] | lr : mwifiex_get_cfp+0x34/0x15c [mwifiex] | sp : ffff8000818b3a70 | x29: ffff8000818b3a70 x28: ffff000006bfd8a5 x27: 0000000000000004 | x26: 000000000000002c x25: 0000000000001511 x24: 0000000002e86bc9 | x23: ffff000006bfd996 x22: 0000000000000004 x21: ffff000007bec000 | x20: 000000000000002c x19: 0000000000000000 x18: 0000000000000000 | x17: 000000040044ffff x16: 00500072b5503510 x15: ccc283740681e517 | x14: 0201000101006d15 x13: 0000000002e8ff43 x12: 002c01000000ffb1 | x11: 0100000000000000 x10: 02e8ff43002c0100 x9 : 0000ffb100100157 | x8 : ffff000003d20000 x7 : 00000000000002f1 x6 : 00000000ffffe124 | x5 : 0000000000000001 x4 : 0000000000000003 x3 : 0000000000000000 | x2 : 0000000000000000 x1 : 0001000000011001 x0 : 0000000000000000 | Call trace: | mwifiex_get_cfp+0xd8/0x15c [mwifiex] | mwifiex_parse_single_response_buf+0x1d0/0x504 [mwifiex] | mwifiex_handle_event_ext_scan_report+0x19c/0x2f8 [mwifiex] | mwifiex_process_sta_event+0x298/0xf0c [mwifiex] | mwifiex_process_event+0x110/0x238 [mwifiex] | mwifiex_main_process+0x428/0xa44 [mwifiex] | mwifiex_sdio_interrupt+0x64/0x12c [mwifiex_sdio] | process_sdio_pending_irqs+0x64/0x1b8 | sdio_irq_work+0x4c/0x7c | process_one_work+0x148/0x2a0 | worker_thread+0x2fc/0x40c | kthread+0x110/0x114 | ret_from_fork+0x10/0x20 | Code: a94153f3 a8c37bfd d50323bf d65f03c0 (f940a000) | ---[ end trace 0000000000000000 ]---
--- drivers/net/wireless/marvell/mwifiex/main.h | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/marvell/mwifiex/main.h +3 -0
@@ -1287,6 +1287,9 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,for (i =0 ; i < adapter->priv_num; i++) {if (adapter->priv[i]) { +if (adapter->priv[i]->bss_mode ==NL80211_IFTYPE_UNSPECIFIED ) +continue ; +if ((adapter->priv[i]->bss_num == bss_num) && (adapter->priv[i]->bss_type == bss_type))break ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 230/375 perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kan Liang <[email protected]>
[ Upstream commit 556a7c039a52c21da33eaae9269984a1ef59189b ]
The below error is observed on Ice Lake VM.
$ perf stat Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (slots). /bin/dmesg | grep -i perf may provide additional information.
In a virtualization env, the Topdown metrics and the slots event haven't been supported yet. The guest CPUID doesn't enumerate them. However, the current kernel unconditionally exposes the slots event and the Topdown metrics events to sysfs, which misleads the perf tool and triggers the error.
Hide the perf-metrics topdown events and the slots event if the perf-metrics feature is not enumerated.
The big core of a hybrid platform can also supports the perf-metrics feature. Fix the hybrid platform as well.
--- arch/x86/events/intel/core.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
arch/x86/events/intel/core.c +33 -1
@@ -5733,8 +5733,22 @@ exra_is_visible(struct kobject *kobj, struct attribute *attr, int i)return x86_pmu.version >=2 ? attr->mode :0 ; } +static umode_t +td_is_visible (struct kobject *kobj,struct attribute *attr,int i) +{ +/* +* Hide the perf metrics topdown events +* if the feature is not enumerated. +*/ +if (x86_pmu.num_topdown_events) +return x86_pmu.intel_cap.perf_metrics ? attr->mode :0 ; + +return attr->mode; +} +static struct attribute_group group_events_td = { .name ="events" , + .is_visible = td_is_visible, };static struct attribute_group group_events_mem = {
@@ -5936,9 +5950,27 @@ static umode_t hybrid_format_is_visible(struct kobject *kobj,return (cpu >=0 ) && (pmu->pmu_type & pmu_attr->pmu_type) ? attr->mode :0 ; } +static umode_t hybrid_td_is_visible (struct kobject *kobj, +struct attribute *attr,int i) +{ +struct device *dev =kobj_to_dev (kobj); +struct x86_hybrid_pmu *pmu = + container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu); + +if (!is_attr_for_this_pmu (kobj, attr)) +return 0 ; + + +/* Only the big core supports perf metrics */ +if (pmu->pmu_type == hybrid_big) +return pmu->intel_cap.perf_metrics ? attr->mode :0 ; + +return attr->mode; +} +static struct attribute_group hybrid_group_events_td = { .name ="events" , - .is_visible = hybrid_events_is_visible, + .is_visible = hybrid_td_is_visible, };static struct attribute_group hybrid_group_events_mem = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 231/375 PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mrinmay Sarkar <[email protected]>
[ Upstream commit 1d648bf79d4dca909f242b1a0cdc458e4f9d0253 ]
Due to some hardware changes, SA8775P has set the NO_SNOOP attribute in its TLP for all the PCIe controllers. NO_SNOOP attribute when set, the requester is indicating that no cache coherency issue exist for the addressed memory on the endpoint i.e., memory is not cached. But in reality, requester cannot assume this unless there is a complete control/visibility over the addressed memory on the endpoint.
And worst case, if the memory is cached on the endpoint, it may lead to memory corruption issues. It should be noted that the caching of memory on the endpoint is not solely dependent on the NO_SNOOP attribute in TLP.
So to avoid the corruption, this patch overrides the NO_SNOOP attribute by setting the PCIE_PARF_NO_SNOOP_OVERIDE register. This patch is not needed for other upstream supported platforms since they do not set NO_SNOOP attribute by default.
8775 has IP version 1.34.0 so introduce a new cfg(cfg_1_34_0) for this platform. Assign override_no_snoop flag into struct qcom_pcie_cfg and set it true in cfg_1_34_0 and enable cache snooping if this particular flag is true.
--- drivers/pci/controller/dwc/pcie-qcom.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
drivers/pci/controller/dwc/pcie-qcom.c +24 -1
@@ -51,6 +51,7 @@#define PARF_SID_OFFSET 0x234#define PARF_BDF_TRANSLATE_CFG 0x24c#define PARF_SLV_ADDR_SPACE_SIZE 0x358 +#define PARF_NO_SNOOP_OVERIDE 0x3d4#define PARF_DEVICE_TYPE 0x1000#define PARF_BDF_TO_SID_TABLE_N 0x2000#define PARF_BDF_TO_SID_CFG 0x2c00
@@ -118,6 +119,10 @@/* PARF_LTSSM register fields */ #define LTSSM_EN BIT(8) +/* PARF_NO_SNOOP_OVERIDE register fields */ +#define WR_NO_SNOOP_OVERIDE_EN BIT(1) +#define RD_NO_SNOOP_OVERIDE_EN BIT(3) +/* PARF_DEVICE_TYPE register fields */ #define DEVICE_TYPE_RC 0x4
@@ -231,8 +236,15 @@ struct qcom_pcie_ops {int (*config_sid)(struct qcom_pcie *pcie); }; +/** +* struct qcom_pcie_cfg - Per SoC config struct +* @ops: qcom PCIe ops structure +* @override_no_snoop: Override NO_SNOOP attribute in TLP to enable cache +* snooping +*/ struct qcom_pcie_cfg {const struct qcom_pcie_ops *ops; +bool override_no_snoop;bool no_l0s; };
@@ -986,6 +998,12 @@ static int qcom_pcie_init_2_7_0(struct qcom_pcie *pcie)static int qcom_pcie_post_init_2_7_0 (struct qcom_pcie *pcie) { +const struct qcom_pcie_cfg *pcie_cfg = pcie->cfg; + +if (pcie_cfg->override_no_snoop) +writel (WR_NO_SNOOP_OVERIDE_EN |RD_NO_SNOOP_OVERIDE_EN , + pcie->parf +PARF_NO_SNOOP_OVERIDE ); +qcom_pcie_clear_aspm_l0s (pcie->pci);qcom_pcie_clear_hpc (pcie->pci);
@@ -1366,6 +1384,11 @@ static const struct qcom_pcie_cfg cfg_1_9_0 = { .ops = &ops_1_9_0, }; +static const struct qcom_pcie_cfg cfg_1_34_0 = { + .ops = &ops_1_9_0, + .override_no_snoop = true, +}; +static const struct qcom_pcie_cfg cfg_2_1_0 = { .ops = &ops_2_1_0, };
@@ -1667,7 +1690,7 @@ static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-msm8996", .data = &cfg_2_3_2 }, { .compatible = "qcom,pcie-qcs404", .data = &cfg_2_4_0 }, { .compatible = "qcom,pcie-sa8540p", .data = &cfg_sc8280xp }, - { .compatible = "qcom,pcie-sa8775p", .data = &cfg_1_9_0}, + { .compatible = "qcom,pcie-sa8775p", .data = &cfg_1_34_0}, { .compatible = "qcom,pcie-sc7280", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sc8180x", .data = &cfg_1_9_0 }, { .compatible = "qcom,pcie-sc8280xp", .data = &cfg_sc8280xp },
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 232/375 staging: vchiq_core: Bubble up wait_event_interruptible() return value
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Umang Jain <[email protected]>
[ Upstream commit c22502cb84d4c963f754e6d943d3133cfa80ba97 ]
wait_event_interruptible() returns if the condition evaluates to true it receives a signal. However, the current code always assume that the wait_event_interruptible() returns only when the event is fired. This should not be the case as wait_event_interruptible() can return on receiving a signal (with -ERESTARTSYS as return value).
We should consider this and bubble up the return value of wait_event_interruptible() to exactly know if the wait has failed and error out. This will also help to properly stop kthreads in the subsequent patch.
Meanwhile at it, remote_wait_event() is modified to return 0 on success, and an error code (from wait_event_interruptible()) on failure. The return value is now checked for remote_wait_event() calls.
--- .../interface/vchiq_arm/vchiq_core.c | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-)
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +24 -7
@@ -501,16 +501,21 @@ remote_event_create(wait_queue_head_t *wq, struct remote_event *event)* routines where switched to the "interruptible" family of functions, as the * former was deemed unjustified and the use "killable" set all VCHIQ's * threads in D state. +* +* Returns: 0 on success, a negative error code on failure */ static inline int remote_event_wait (wait_queue_head_t *wq,struct remote_event *event) { +int ret =0 ; +if (!event->fired) { event->armed =1 ;dsb (sy); -if (wait_event_interruptible (*wq, event->fired)) { + ret =wait_event_interruptible (*wq, event->fired); +if (ret) { event->armed =0 ; -return 0 ; +return ret; } event->armed =0 ;/* Ensure that the peer sees that we are not waiting (armed == 0). */
@@ -518,7 +523,7 @@ remote_event_wait(wait_queue_head_t *wq, struct remote_event *event) } event->fired =0 ; -return 1 ; +return ret; }/*
@@ -1140,6 +1145,7 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service,struct vchiq_header *header;ssize_t callback_result;int svc_fourcc; +int ret; local = state->local;
@@ -1147,7 +1153,9 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, mutex_lock_killable(&state->sync_mutex))return -EAGAIN ; -remote_event_wait (&state->sync_release_event, &local->sync_release); + ret =remote_event_wait (&state->sync_release_event, &local->sync_release); +if (ret) +return ret;/* Ensure that reads don't overtake the remote_event_wait. */ rmb ();
@@ -1929,13 +1937,16 @@ slot_handler_func(void *v) {struct vchiq_state *state = v;struct vchiq_shared_state *local = state->local; +int ret;DEBUG_INITIALISE (local);while (1 ) {DEBUG_COUNT (SLOT_HANDLER_COUNT );DEBUG_TRACE (SLOT_HANDLER_LINE ); -remote_event_wait (&state->trigger_event, &local->trigger); + ret =remote_event_wait (&state->trigger_event, &local->trigger); +if (ret) +return ret;/* Ensure that reads don't overtake the remote_event_wait. */ rmb ();
@@ -1966,6 +1977,7 @@ recycle_func(void *v)struct vchiq_shared_state *local = state->local;u32 *found;size_t length; +int ret; length =sizeof (*found) *BITSET_SIZE (VCHIQ_MAX_SERVICES );
@@ -1975,7 +1987,9 @@ recycle_func(void *v)return -ENOMEM ;while (1 ) { -remote_event_wait (&state->recycle_event, &local->recycle); + ret =remote_event_wait (&state->recycle_event, &local->recycle); +if (ret) +return ret;process_free_queue (state, found, length); }
@@ -1992,6 +2006,7 @@ sync_func(void *v) (struct vchiq_header *)SLOT_DATA_FROM_INDEX (state, state->remote->slot_sync);int svc_fourcc; +int ret;while (1 ) {struct vchiq_service *service;
@@ -1999,7 +2014,9 @@ sync_func(void *v)int type;unsigned int localport, remoteport; -remote_event_wait (&state->sync_trigger_event, &local->sync_trigger); + ret =remote_event_wait (&state->sync_trigger_event, &local->sync_trigger); +if (ret) +return ret;/* Ensure that reads don't overtake the remote_event_wait. */ rmb ();
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 233/375 iommufd: Require drivers to supply the cache_invalidate_user ops
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit a11dda723c6493bb1853bbc61c093377f96e2d47 ]
If drivers don't do this then iommufd will oops invalidation ioctls with something like:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Mem abort info:
ESR = 0x0000000086000004
EC = 0x21: IABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
user pgtable: 4k pages, 48-bit VAs, pgdp=0000000101059000
[0000000000000000] pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 0000000086000004 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 371 Comm: qemu-system-aar Not tainted 6.8.0-rc7-gde77230ac23a #9
Hardware name: linux,dummy-virt (DT)
pstate: 81400809 (Nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=-c)
pc : 0x0
lr : iommufd_hwpt_invalidate+0xa4/0x204
sp : ffff800080f3bcc0
x29: ffff800080f3bcf0 x28: ffff0000c369b300 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
x23: 0000000000000000 x22: 00000000c1e334a0 x21: ffff0000c1e334a0
x20: ffff800080f3bd38 x19: ffff800080f3bd58 x18: 0000000000000000
x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffff8240d6d8
x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000
x8 : 0000001000000002 x7 : 0000fffeac1ec950 x6 : 0000000000000000
x5 : ffff800080f3bd78 x4 : 0000000000000003 x3 : 0000000000000002
x2 : 0000000000000000 x1 : ffff800080f3bcc8 x0 : ffff0000c6034d80
Call trace:
0x0
iommufd_fops_ioctl+0x154/0x274
__arm64_sys_ioctl+0xac/0xf0
invoke_syscall+0x48/0x110
el0_svc_common.constprop.0+0x40/0xe0
do_el0_svc+0x1c/0x28
el0_svc+0x34/0xb4
el0t_64_sync_handler+0x120/0x12c
el0t_64_sync+0x190/0x194All existing drivers implement this op for nesting, this is mostly a bisection aid.
--- drivers/iommu/iommufd/hw_pagetable.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iommu/iommufd/hw_pagetable.c +2 -1
@@ -236,7 +236,8 @@ iommufd_hwpt_nested_alloc(struct iommufd_ctx *ictx, } hwpt->domain->owner = ops; -if (WARN_ON_ONCE (hwpt->domain->type !=IOMMU_DOMAIN_NESTED )) { +if (WARN_ON_ONCE (hwpt->domain->type !=IOMMU_DOMAIN_NESTED || + !hwpt->domain->ops->cache_invalidate_user)) { rc = -EINVAL ; goto out_abort; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 234/375 bpf: Remove tst_run from lwt_seg6local_prog_ops.
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit c13fda93aca118b8e5cd202e339046728ee7dddb ]
The syzbot reported that the lwt_seg6 related BPF ops can be invoked via bpf_test_run() without without entering input_action_end_bpf() first.
Martin KaFai Lau said that self test for BPF_PROG_TYPE_LWT_SEG6LOCAL probably didn't work since it was introduced in commit 04d4b274e2a ("ipv6: sr: Add seg6local action End.BPF"). The reason is that the per-CPU variable seg6_bpf_srh_states::srh is never assigned in the self test case but each BPF function expects it.
Remove test_run for BPF_PROG_TYPE_LWT_SEG6LOCAL.
--- net/core/filter.c | 1 - 1 file changed, 1 deletion(-)
net/core/filter.c +0 -1
@@ -11047,7 +11047,6 @@ const struct bpf_verifier_ops lwt_seg6local_verifier_ops = { };const struct bpf_prog_ops lwt_seg6local_prog_ops = { - .test_run = bpf_prog_test_run_skb, };const struct bpf_verifier_ops cg_sock_verifier_ops = {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 235/375 watchdog: imx7ulp_wdt: keep already running watchdog enabled
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
[ Upstream commit b771d14f417e9d8030ab000b3341cf71266be90e ]
When the bootloader enabled the watchdog before Kernel started then keep it enabled during initialization. Otherwise the time between the watchdog probing and the userspace taking over the watchdog won't be covered by the watchdog. When keeping the watchdog enabled inform the Kernel about this by setting the WDOG_HW_RUNNING so that the periodic watchdog feeder is started when desired.
--- drivers/watchdog/imx7ulp_wdt.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/watchdog/imx7ulp_wdt.c +5 -0
@@ -290,6 +290,11 @@ static int imx7ulp_wdt_init(struct imx7ulp_wdt_device *wdt, unsigned int timeoutif (wdt->ext_reset) val |=WDOG_CS_INT_EN ; +if (readl (wdt->base +WDOG_CS ) &WDOG_CS_EN ) { +set_bit (WDOG_HW_RUNNING , &wdt->wdd.status); + val |=WDOG_CS_EN ; + } + do { ret = _imx7ulp_wdt_init(wdt, timeout, val); toval = readl(wdt->base + WDOG_TOVAL);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 236/375 drm/amdgpu: reject gang submit on reserved VMIDs
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <[email protected]>
[ Upstream commit 320debca1ba3a81c87247eac84eff976ead09ee0 ]
A gang submit won't work if the VMID is reserved and we can't flush out VM changes from multiple engines at the same time.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 15 +++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 15 ++++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +15 -0
@@ -1096,6 +1096,21 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)unsigned int i;int r; +/* +* We can't use gang submit on with reserved VMIDs when the VM changes +* can't be invalidated by more than one engine at the same time. +*/ +if (p->gang_size >1 && !p->adev->vm_manager.concurrent_flush) { +for (i =0 ; i < p->gang_size; ++i) { +struct drm_sched_entity *entity = p->entities[i]; +struct drm_gpu_scheduler *sched = entity->rq->sched; +struct amdgpu_ring *ring =to_amdgpu_ring (sched); + +if (amdgpu_vmid_uses_reserved (vm, ring->vm_hub)) +return -EINVAL ; + } + } + r =amdgpu_vm_clear_freed (adev, vm,NULL );if (r)return r;
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +14 -1
@@ -406,7 +406,7 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,if (r || !idle) goto error; -if (vm->reserved_vmid[vmhub] || (enforce_isolation && (vmhub ==AMDGPU_GFXHUB (0 )))) { +if (amdgpu_vmid_uses_reserved (vm, vmhub)) { r =amdgpu_vmid_grab_reserved (vm, ring, job, &id, fence);if (r || !id) goto error;
@@ -456,6 +456,19 @@ int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,return r; } +/* +* amdgpu_vmid_uses_reserved - check if a VM will use a reserved VMID +* @vm: the VM to check +* @vmhub: the VMHUB which will be used +* +* Returns: True if the VM will use a reserved VMID. +*/ +bool amdgpu_vmid_uses_reserved (struct amdgpu_vm *vm,unsigned int vmhub) +{ +return vm->reserved_vmid[vmhub] || + (enforce_isolation && (vmhub ==AMDGPU_GFXHUB (0 ))); +} +int amdgpu_vmid_alloc_reserved (struct amdgpu_device *adev,unsigned vmhub) {
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h +1 -0
@@ -78,6 +78,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv,bool amdgpu_vmid_had_gpu_reset (struct amdgpu_device *adev,struct amdgpu_vmid *id); +bool amdgpu_vmid_uses_reserved (struct amdgpu_vm *vm,unsigned int vmhub);int amdgpu_vmid_alloc_reserved (struct amdgpu_device *adev,unsigned vmhub); void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 237/375 smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zqiang <[email protected]>
[ Upstream commit 77aeb1b685f9db73d276bad4bb30d48505a6fd23 ]
For CONFIG_DEBUG_OBJECTS_WORK=y kernels sscs.work defined by INIT_WORK_ONSTACK() is initialized by debug_object_init_on_stack() for the debug check in __init_work() to work correctly.
But this lacks the counterpart to remove the tracked object from debug objects again, which will cause a debug object warning once the stack is freed.
Add the missing destroy_work_on_stack() invocation to cure that.
[ tglx: Massaged changelog ]
--- kernel/smp.c | 1 + 1 file changed, 1 insertion(+)
kernel/smp.c +1 -0
@@ -1119,6 +1119,7 @@ int smp_call_on_cpu(unsigned int cpu, int (*func)(void *), void *par, bool phys)queue_work_on (cpu, system_wq, &sscs.work);wait_for_completion (&sscs.done); +destroy_work_on_stack (&sscs.work);return sscs.ret; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 238/375 fs/ntfs3: Check more cases when directory is corrupted
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <[email protected]>
[ Upstream commit 744375343662058cbfda96d871786e5a5cbe1947 ]
Mark ntfs dirty in this case.
Rename ntfs_filldir to ntfs_dir_emit.
--- fs/ntfs3/dir.c | 52 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 20 deletions(-)
fs/ntfs3/dir.c +32 -20
@@ -272,9 +272,12 @@ struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni,return err == -ENOENT ?NULL : err ?ERR_PTR (err) : inode; } -static inline int ntfs_filldir (struct ntfs_sb_info *sbi,struct ntfs_inode *ni, -const struct NTFS_DE *e,u8 *name, -struct dir_context *ctx) +/* +* returns false if 'ctx' if full +*/ +static inline bool ntfs_dir_emit (struct ntfs_sb_info *sbi, +struct ntfs_inode *ni,const struct NTFS_DE *e, +u8 *name,struct dir_context *ctx) {const struct ATTR_FILE_NAME *fname;unsigned long ino;
@@ -284,29 +287,29 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, fname =Add2Ptr (e,sizeof (struct NTFS_DE ));if (fname->type ==FILE_NAME_DOS ) -return 0 ; +return true;if (!mi_is_ref (&ni->mi, &fname->home)) -return 0 ; +return true; ino =ino_get (&e->ref);if (ino ==MFT_REC_ROOT ) -return 0 ; +return true;/* Skip meta files. Unless option to show metafiles is set. */ if (!sbi->options->showmeta &&ntfs_is_meta_file (sbi, ino)) -return 0 ; +return true;if (sbi->options->nohidden && (fname->dup.fa &FILE_ATTRIBUTE_HIDDEN )) -return 0 ; +return true; name_len =ntfs_utf16_to_nls (sbi, fname->name, fname->name_len, name,PATH_MAX );if (name_len <=0 ) {ntfs_warn (sbi->sb,"failed to convert name for inode %lx." , ino); -return 0 ; +return true; }/*
@@ -336,17 +339,20 @@ static inline int ntfs_filldir(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, } } -return !dir_emit (ctx, (s8 *)name, name_len, ino, dt_type); +return dir_emit (ctx, (s8 *)name, name_len, ino, dt_type); }/* * ntfs_read_hdr - Helper function for ntfs_readdir(). +* +* returns 0 if ok. +* returns -EINVAL if directory is corrupted. +* returns +1 if 'ctx' is full. */ static int ntfs_read_hdr (struct ntfs_sb_info *sbi,struct ntfs_inode *ni,const struct INDEX_HDR *hdr,u64 vbo,u64 pos,u8 *name,struct dir_context *ctx) { -int err;const struct NTFS_DE *e;u32 e_size;u32 end =le32_to_cpu (hdr->used);
@@ -354,12 +360,12 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,for (;; off += e_size) {if (off +sizeof (struct NTFS_DE ) > end) -return -1 ; +return -EINVAL ; e =Add2Ptr (hdr, off); e_size =le16_to_cpu (e->size);if (e_size <sizeof (struct NTFS_DE ) || off + e_size > end) -return -1 ; +return -EINVAL ;if (de_is_last (e))return 0 ;
@@ -369,14 +375,15 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni,continue ;if (le16_to_cpu (e->key_size) <SIZEOF_ATTRIBUTE_FILENAME ) -return -1 ; +return -EINVAL ; ctx->pos = vbo + off;/* Submit the name to the filldir callback. */ - err =ntfs_filldir (sbi, ni, e, name, ctx); -if (err) -return err; +if (!ntfs_dir_emit (sbi, ni, e, name, ctx)) { +/* ctx is full. */ +return +1 ; + } } }
@@ -475,8 +482,6 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx) vbo = (u64 )bit << index_bits;if (vbo >= i_size) { -ntfs_inode_err (dir,"Looks like your dir is corrupt" ); - ctx->pos = eod; err = -EINVAL ; goto out; }
@@ -499,9 +504,16 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx)__putname (name);put_indx_node (node); -if (err == -ENOENT ) { +if (err ==1 ) { +/* 'ctx' is full. */ + err =0 ; + }else if (err == -ENOENT ) { err =0 ; ctx->pos = pos; + }else if (err <0 ) { +if (err == -EINVAL ) +ntfs_inode_err (dir,"directory corrupted" ); + ctx->pos = eod; }return err;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 239/375 btrfs: slightly loosen the requirement for qgroup removal
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
[ Upstream commit a776bf5f3c2300cfdf8a195663460b1793ac9847 ]
[BUG]
Currently if one is utilizing "qgroups/drop_subtree_threshold" sysfs, and a snapshot with level higher than that value is dropped, we will not be able to delete the qgroup until next qgroup rescan:
uuid=ffffffff-eeee-dddd-cccc-000000000000
wipefs -fa $dev
mkfs.btrfs -f $dev -O quota -s 4k -n 4k -U $uuid mount $dev $mnt
btrfs subvolume create $mnt/subv1/ for (( i = 0; i < 1024; i++ )); do xfs_io -f -c "pwrite 0 2k" $mnt/subv1/file_$i > /dev/null done sync btrfs subvolume snapshot $mnt/subv1 $mnt/snapshot btrfs quota enable $mnt btrfs quota rescan -w $mnt sync echo 1 > /sys/fs/btrfs/$uuid/qgroups/drop_subtree_threshold btrfs subvolume delete $mnt/snapshot btrfs subvolume sync $mnt btrfs qgroup show -prce --sync $mnt btrfs qgroup destroy 0/257 $mnt umount $mnt
The final qgroup removal would fail with the following error:
ERROR: unable to destroy quota group: Device or resource busy
[CAUSE]
The above script would generate a subvolume of level 2, then snapshot it, enable qgroup, set the drop_subtree_threshold, then drop the snapshot.
Since the subvolume drop would meet the threshold, qgroup would be marked inconsistent and skip accounting to avoid hanging the system at transaction commit.
But currently we do not allow a qgroup with any rfer/excl numbers to be dropped, and this is not really compatible with the new drop_subtree_threshold behavior.
[FIX]
Only require the strict zero rfer/excl/rfer_cmpr/excl_cmpr for squota mode. This is due to the fact that squota can never go inconsistent, and it can have dropped subvolume but with non-zero qgroup numbers for future accounting.
For full qgroup mode, we only check if there is a subvolume for it.
--- fs/btrfs/qgroup.c | 87 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-)
fs/btrfs/qgroup.c +80 -7
@@ -1750,13 +1750,55 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid)return ret; } -static bool qgroup_has_usage (struct btrfs_qgroup *qgroup) +/* +* Return 0 if we can not delete the qgroup (not empty or has children etc). +* Return >0 if we can delete the qgroup. +* Return <0 for other errors during tree search. +*/ +static int can_delete_qgroup (struct btrfs_fs_info *fs_info,struct btrfs_qgroup *qgroup) { -return (qgroup->rfer >0 || qgroup->rfer_cmpr >0 || - qgroup->excl >0 || qgroup->excl_cmpr >0 || - qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA ] >0 || - qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC ] >0 || - qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS ] >0 ); +struct btrfs_key key; +struct btrfs_path *path; +int ret; + +/* +* Squota would never be inconsistent, but there can still be case +* where a dropped subvolume still has qgroup numbers, and squota +* relies on such qgroup for future accounting. +* +* So for squota, do not allow dropping any non-zero qgroup. +*/ +if (btrfs_qgroup_mode (fs_info) ==BTRFS_QGROUP_MODE_SIMPLE && + (qgroup->rfer || qgroup->excl || qgroup->excl_cmpr || qgroup->rfer_cmpr)) +return 0 ; + +/* For higher level qgroup, we can only delete it if it has no child. */ +if (btrfs_qgroup_level (qgroup->qgroupid)) { +if (!list_empty (&qgroup->members)) +return 0 ; +return 1 ; + } + +/* +* For level-0 qgroups, we can only delete it if it has no subvolume +* for it. +* This means even a subvolume is unlinked but not yet fully dropped, +* we can not delete the qgroup. +*/ + key.objectid = qgroup->qgroupid; + key.type =BTRFS_ROOT_ITEM_KEY ; + key.offset =-1ULL ; + path =btrfs_alloc_path (); +if (!path) +return -ENOMEM ; + + ret =btrfs_find_root (fs_info->tree_root, &key, path,NULL ,NULL ); +btrfs_free_path (path); +/* +* The @ret from btrfs_find_root() exactly matches our definition for +* the return value, thus can be returned directly. +*/ +return ret; }int btrfs_remove_qgroup (struct btrfs_trans_handle *trans,u64 qgroupid)
@@ -1778,7 +1820,10 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) goto out; } -if (is_fstree (qgroupid) &&qgroup_has_usage (qgroup)) { + ret =can_delete_qgroup (fs_info, qgroup); +if (ret <0 ) + goto out; +if (ret ==0 ) { ret = -EBUSY ; goto out; }
@@ -1803,6 +1848,34 @@ int btrfs_remove_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) }spin_lock (&fs_info->qgroup_lock); +/* +* Warn on reserved space. The subvolume should has no child nor +* corresponding subvolume. +* Thus its reserved space should all be zero, no matter if qgroup +* is consistent or the mode. +*/ +WARN_ON (qgroup->rsv.values[BTRFS_QGROUP_RSV_DATA ] || + qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC ] || + qgroup->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS ]); +/* +* The same for rfer/excl numbers, but that's only if our qgroup is +* consistent and if it's in regular qgroup mode. +* For simple mode it's not as accurate thus we can hit non-zero values +* very frequently. +*/ +if (btrfs_qgroup_mode (fs_info) ==BTRFS_QGROUP_MODE_FULL && + !(fs_info->qgroup_flags &BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT )) { +if (WARN_ON (qgroup->rfer || qgroup->excl || + qgroup->rfer_cmpr || qgroup->excl_cmpr)) { +btrfs_warn_rl (fs_info, +"to be deleted qgroup %u/%llu has non-zero numbers, rfer %llu rfer_cmpr %llu excl %llu excl_cmpr %llu" , +btrfs_qgroup_level (qgroup->qgroupid), +btrfs_qgroup_subvolid (qgroup->qgroupid), + qgroup->rfer, qgroup->rfer_cmpr, + qgroup->excl, qgroup->excl_cmpr); +qgroup_mark_inconsistent (fs_info); + } + }del_qgroup_rb (fs_info, qgroupid);spin_unlock (&fs_info->qgroup_lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 240/375 btrfs: dont BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit a580fb2c3479d993556e1c31b237c9e5be4944a3 ]
We handle errors here properly, ENOMEM isn't fatal, return the error.
--- fs/btrfs/extent-tree.c | 1 - 1 file changed, 1 deletion(-)
fs/btrfs/extent-tree.c +0 -1
@@ -5339,7 +5339,6 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, &wc->refs[level], &wc->flags[level], NULL); -BUG_ON (ret == -ENOMEM );if (ret)return ret;BUG_ON (wc->refs[level] ==0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 241/375 btrfs: replace BUG_ON with ASSERT in walk_down_proc()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 1f9d44c0a12730a24f8bb75c5e1102207413cc9b ]
We have a couple of areas where we check to make sure the tree block is locked before looking up or messing with references. This is old code so it has this as BUG_ON(). Convert this to ASSERT() for developers.
--- fs/btrfs/extent-tree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/btrfs/extent-tree.c +2 -2
@@ -5333,7 +5333,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,if (lookup_info && ((wc->stage ==DROP_REFERENCE && wc->refs[level] !=1 ) || (wc->stage ==UPDATE_BACKREF && !(wc->flags[level] & flag)))) { -BUG_ON (!path->locks[level]); +ASSERT (path->locks[level]); ret = btrfs_lookup_extent_info(trans, fs_info, eb->start, level, 1, &wc->refs[level],
@@ -5357,7 +5357,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,/* wc->stage == UPDATE_BACKREF */ if (!(wc->flags[level] & flag)) { -BUG_ON (!path->locks[level]); +ASSERT (path->locks[level]); ret =btrfs_inc_ref (trans, root, eb,1 );BUG_ON (ret);/* -ENOMEM */ ret =btrfs_dec_ref (trans, root, eb,0 );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 242/375 btrfs: clean up our handling of refs == 0 in snapshot delete
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit b8ccef048354074a548f108e51d0557d6adfd3a3 ]
In reada we BUG_ON(refs == 0), which could be unkind since we aren't holding a lock on the extent leaf and thus could get a transient incorrect answer. In walk_down_proc we also BUG_ON(refs == 0), which could happen if we have extent tree corruption. Change that to return -EUCLEAN. In do_walk_down() we catch this case and handle it correctly, however we return -EIO, which -EUCLEAN is a more appropriate error code. Finally in walk_up_proc we have the same BUG_ON(refs == 0), so convert that to proper error handling. Also adjust the error message so we can actually do something with the information.
--- fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
fs/btrfs/extent-tree.c +23 -5
@@ -5275,7 +5275,15 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,/* We don't care about errors in readahead. */ if (ret <0 )continue ; -BUG_ON (refs ==0 ); + +/* +* This could be racey, it's conceivable that we raced and end +* up with a bogus refs count, if that's the case just skip, if +* we are actually corrupt we will notice when we look up +* everything again with our locks. +*/ +if (refs ==0 ) +continue ;if (wc->stage ==DROP_REFERENCE ) {if (refs ==1 )
@@ -5341,7 +5349,11 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, NULL);if (ret)return ret; -BUG_ON (wc->refs[level] ==0 ); +if (unlikely (wc->refs[level] ==0 )) { +btrfs_err (fs_info,"bytenr %llu has 0 references, expect > 0" , + eb->start); +return -EUCLEAN ; + } }if (wc->stage ==DROP_REFERENCE ) {
@@ -5514,8 +5526,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, goto out_unlock;if (unlikely (wc->refs[level -1 ] ==0 )) { -btrfs_err (fs_info,"Missing references." ); - ret = -EIO ; +btrfs_err (fs_info,"bytenr %llu has 0 references, expect > 0" , + bytenr); + ret = -EUCLEAN ; goto out_unlock; } *lookup_info =0 ;
@@ -5718,7 +5731,12 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, path->locks[level] =0 ;return ret; } -BUG_ON (wc->refs[level] ==0 ); +if (unlikely (wc->refs[level] ==0 )) { +btrfs_tree_unlock_rw (eb, path->locks[level]); +btrfs_err (fs_info,"bytenr %llu has 0 references, expect > 0" , + eb->start); +return -EUCLEAN ; + }if (wc->refs[level] ==1 ) {btrfs_tree_unlock_rw (eb, path->locks[level]); path->locks[level] =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 243/375 btrfs: handle errors from btrfs_dec_ref() properly
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
[ Upstream commit 5eb178f373b4f16f3b42d55ff88fc94dd95b93b1 ]
In walk_up_proc() we BUG_ON(ret) from btrfs_dec_ref(). This is incorrect, we have proper error handling here, return the error.
--- fs/btrfs/extent-tree.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/btrfs/extent-tree.c +4 -1
@@ -5754,7 +5754,10 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, ret =btrfs_dec_ref (trans, root, eb,1 ); else ret =btrfs_dec_ref (trans, root, eb,0 ); -BUG_ON (ret);/* -ENOMEM */ +if (ret) { +btrfs_abort_transaction (trans, ret); +return ret; + }if (is_fstree (btrfs_root_id (root))) { ret =btrfs_qgroup_trace_leaf_items (trans, eb);if (ret) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 244/375 btrfs: replace BUG_ON() with error handling at update_ref_for_cow()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit b56329a782314fde5b61058e2a25097af7ccb675 ]
Instead of a BUG_ON() just return an error, log an error message and abort the transaction in case we find an extent buffer belonging to the relocation tree that doesn't have the full backref flag set. This is unexpected and should never happen (save for bugs or a potential bad memory).
--- fs/btrfs/ctree.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
fs/btrfs/ctree.c +10 -2
@@ -462,8 +462,16 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, } owner =btrfs_header_owner (buf); -BUG_ON (owner ==BTRFS_TREE_RELOC_OBJECTID && - !(flags &BTRFS_BLOCK_FLAG_FULL_BACKREF )); +if (unlikely (owner ==BTRFS_TREE_RELOC_OBJECTID && + !(flags &BTRFS_BLOCK_FLAG_FULL_BACKREF ))) { +btrfs_crit (fs_info, +"found tree block at bytenr %llu level %d root %llu refs %llu flags %llx without full backref flag set" , + buf->start,btrfs_header_level (buf), +btrfs_root_id (root), refs, flags); + ret = -EUCLEAN ; +btrfs_abort_transaction (trans, ret); +return ret; + }if (refs >1 ) { if ((owner == btrfs_root_id(root) ||
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 245/375 btrfs: dont BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
[ Upstream commit 28cb13f29faf6290597b24b728dc3100c019356f ]
Instead of doing a BUG_ON() handle the error by returning -EUCLEAN, aborting the transaction and logging an error message.
--- fs/btrfs/extent-tree.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
fs/btrfs/extent-tree.c +20 -4
@@ -173,9 +173,16 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); num_refs =btrfs_extent_refs (leaf, ei); +if (unlikely (num_refs ==0 )) { + ret = -EUCLEAN ; +btrfs_err (fs_info, +"unexpected zero reference count for extent item (%llu %u %llu)" , + key.objectid, key.type, key.offset); +btrfs_abort_transaction (trans, ret); + goto out_free; + } extent_flags =btrfs_extent_flags (leaf, ei); owner =btrfs_get_extent_owner_root (fs_info, leaf, path->slots[0 ]); -BUG_ON (num_refs ==0 ); }else { num_refs =0 ; extent_flags =0 ;
@@ -205,10 +212,19 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, goto search_again; }spin_lock (&head->lock); -if (head->extent_op && head->extent_op->update_flags) +if (head->extent_op && head->extent_op->update_flags) { extent_flags |= head->extent_op->flags_to_set; -else -BUG_ON (num_refs ==0 ); + }else if (unlikely (num_refs ==0 )) { +spin_unlock (&head->lock); +mutex_unlock (&head->mutex); +spin_unlock (&delayed_refs->lock); + ret = -EUCLEAN ; +btrfs_err (fs_info, +"unexpected zero reference count for extent %llu (%s)" , + bytenr, metadata ?"metadata" :"data" ); +btrfs_abort_transaction (trans, ret); + goto out_free; + } num_refs += head->ref_mod;spin_unlock (&head->lock);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 246/375 ethtool: fail closed if we cant get max channel used in indirection tables
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 2899d58462ba868287d6ff3acad3675e7adf934f ]
Commit 0d1b7d6c9274 ("bnxt: fix crashes when reducing ring count with active RSS contexts") proves that allowing indirection table to contain channels with out of bounds IDs may lead to crashes. Currently the max channel check in the core gets skipped if driver can't fetch the indirection table or when we can't allocate memory.
Both of those conditions should be extremely rare but if they do happen we should try to be safe and fail the channel change.
--- net/ethtool/channels.c | 6 ++---- net/ethtool/common.c | 26 +++++++++++++++----------- net/ethtool/common.h | 2 +- net/ethtool/ioctl.c | 4 +--- 4 files changed, 19 insertions(+), 19 deletions(-)
net/ethtool/channels.c +2 -4
@@ -171,11 +171,9 @@ ethnl_set_channels(struct ethnl_req_info *req_info, struct genl_info *info)*/ if (ethtool_get_max_rxnfc_channel (dev, &max_rxnfc_in_use)) max_rxnfc_in_use =0 ; -if (!netif_is_rxfh_configured (dev) || -ethtool_get_max_rxfh_channel (dev, &max_rxfh_in_use)) - max_rxfh_in_use =0 ; + max_rxfh_in_use =ethtool_get_max_rxfh_channel (dev);if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) { -GENL_SET_ERR_MSG (info,"requested channel counts are too low for existing indirection table settings" ); +GENL_SET_ERR_MSG_FMT (info,"requested channel counts are too low for existing indirection table (%d)" , max_rxfh_in_use);return -EINVAL ; }if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) {
net/ethtool/common.c +15 -11
@@ -587,35 +587,39 @@ int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max)return err; } -int ethtool_get_max_rxfh_channel (struct net_device *dev,u32 *max) +u32 ethtool_get_max_rxfh_channel (struct net_device *dev) {struct ethtool_rxfh_param rxfh = {}; -u32 dev_size, current_max =0 ; +u32 dev_size, current_max;int ret; +if (!netif_is_rxfh_configured (dev)) +return 0 ; +if (!dev->ethtool_ops->get_rxfh_indir_size || !dev->ethtool_ops->get_rxfh) -return -EOPNOTSUPP ; +return 0 ; dev_size = dev->ethtool_ops->get_rxfh_indir_size (dev);if (dev_size ==0 ) -return -EOPNOTSUPP ; +return 0 ; rxfh.indir =kcalloc (dev_size,sizeof (rxfh.indir[0 ]),GFP_USER );if (!rxfh.indir) -return -ENOMEM ; +return U32_MAX ; ret = dev->ethtool_ops->get_rxfh (dev, &rxfh); -if (ret) - goto out; +if (ret) { + current_max =U32_MAX ; + goto out_free; + } + current_max =0 ;while (dev_size--) current_max =max (current_max, rxfh.indir[dev_size]); - *max = current_max; - -out: +out_free:kfree (rxfh.indir); -return ret; +return current_max; }int ethtool_check_ops (const struct ethtool_ops *ops)
net/ethtool/common.h +1 -1
@@ -42,7 +42,7 @@ int __ethtool_get_link(struct net_device *dev);bool convert_legacy_settings_to_link_ksettings (struct ethtool_link_ksettings *link_ksettings,const struct ethtool_cmd *legacy_settings); -int ethtool_get_max_rxfh_channel (struct net_device *dev,u32 *max); +u32 ethtool_get_max_rxfh_channel (struct net_device *dev);int ethtool_get_max_rxnfc_channel (struct net_device *dev,u64 *max);int __ethtool_get_ts_info (struct net_device *dev,struct ethtool_ts_info *info);
net/ethtool/ioctl.c +1 -3
@@ -1928,9 +1928,7 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,* indirection table/rxnfc settings */ if (ethtool_get_max_rxnfc_channel (dev, &max_rxnfc_in_use)) max_rxnfc_in_use =0 ; -if (!netif_is_rxfh_configured (dev) || -ethtool_get_max_rxfh_channel (dev, &max_rxfh_in_use)) - max_rxfh_in_use =0 ; + max_rxfh_in_use =ethtool_get_max_rxfh_channel (dev);if (channels.combined_count + channels.rx_count <=max_t (u64, max_rxnfc_in_use, max_rxfh_in_use))return -EINVAL ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 247/375 cxl/region: Verify target positions using the ordered target list
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alison Schofield <[email protected]>
[ Upstream commit 82a3e3a235633aa0575fac9507d648dd80f3437f ]
When a root decoder is configured the interleave target list is read from the BIOS populated CFMWS structure. Per the CXL spec 3.1 Table 9-22 the target list is in interleave order. The CXL driver populates its decoder target list in the same order and stores it in 'struct cxl_switch_decoder' field "@target: active ordered target list in current decoder configuration"
Given the promise of an ordered list, the driver can stop duplicating the work of BIOS and simply check target positions against the ordered list during region configuration.
The simplified check against the ordered list is presented here. A follow-on patch will remove the unused code.
For Modulo arithmetic this is not a fix, only a simplification. For XOR arithmetic this is a fix for HB IW of 3,6,12.
--- drivers/cxl/core/region.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/cxl/core/region.c +4 -1
@@ -1632,10 +1632,13 @@ static int cxl_region_attach_position(struct cxl_region *cxlr, const struct cxl_dport *dport, int pos) {struct cxl_memdev *cxlmd =cxled_to_memdev (cxled); +struct cxl_switch_decoder *cxlsd = &cxlrd->cxlsd; +struct cxl_decoder *cxld = &cxlsd->cxld; +int iw = cxld->interleave_ways;struct cxl_port *iter;int rc; -if (cxlrd->calc_hb (cxlrd, pos) != dport) { +if (dport != cxlrd->cxlsd.target[pos % iw]) {dev_dbg (&cxlr->dev,"%s:%s invalid target position for %s\n" ,dev_name (&cxlmd->dev),dev_name (&cxled->cxld.dev),dev_name (&cxlrd->cxlsd.cxld.dev));
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 248/375 riscv: set trap vector earlier
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: yang.zhang <[email protected]>
[ Upstream commit 6ad8735994b854b23c824dd6b1dd2126e893a3b4 ]
The exception vector of the booting hart is not set before enabling the mmu and then still points to the value of the previous firmware, typically _start. That makes it hard to debug setup_vm() when bad things happen. So fix that by setting the exception vector earlier.
--- arch/riscv/kernel/head.S | 3 +++ 1 file changed, 3 insertions(+)
arch/riscv/kernel/head.S +3 -0
@@ -305,6 +305,9 @@ SYM_CODE_START(_start_kernel) #else mv a0, a1 #endif /* CONFIG_BUILTIN_DTB */ + /* Set trap vector to spin forever to help debug */ + la a3, .Lsecondary_park + csrw CSR_TVEC, a3 call setup_vm #ifdef CONFIG_MMU la a0, early_pg_dir
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 249/375 PCI: Add missing bridge lock to pci_bus_lock()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <[email protected]>
[ Upstream commit a4e772898f8bf2e7e1cf661a12c60a5612c4afab ]
One of the true positives that the cfg_access_lock lockdep effort identified is this sequence:
WARNING: CPU: 14 PID: 1 at drivers/pci/pci.c:4886 pci_bridge_secondary_bus_reset+0x5d/0x70 RIP: 0010:pci_bridge_secondary_bus_reset+0x5d/0x70 Call Trace: <TASK> ? __warn+0x8c/0x190 ? pci_bridge_secondary_bus_reset+0x5d/0x70 ? report_bug+0x1f8/0x200 ? handle_bug+0x3c/0x70 ? exc_invalid_op+0x18/0x70 ? asm_exc_invalid_op+0x1a/0x20 ? pci_bridge_secondary_bus_reset+0x5d/0x70 pci_reset_bus+0x1d8/0x270 vmd_probe+0x778/0xa10 pci_device_probe+0x95/0x120
Where pci_reset_bus() users are triggering unlocked secondary bus resets. Ironically pci_bus_reset(), several calls down from pci_reset_bus(), uses pci_bus_lock() before issuing the reset which locks everything *but* the bridge itself.
For the same motivation as adding:
bridge = pci_upstream_bridge(dev);
if (bridge)
pci_dev_lock(bridge);to pci_reset_function() for the "bus" and "cxl_bus" reset cases, add pci_dev_lock() for @bus->self to pci_bus_lock().
[bhelgaas: squash in recursive locking deadlock fix from Keith Busch:
https://lore.kernel.org/r/[email protected]]
--- drivers/pci/pci.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
drivers/pci/pci.c +21 -14
@@ -5441,10 +5441,12 @@ static void pci_bus_lock(struct pci_bus *bus) {struct pci_dev *dev; +pci_dev_lock (bus->self);list_for_each_entry (dev, &bus->devices, bus_list) { -pci_dev_lock (dev);if (dev->subordinate)pci_bus_lock (dev->subordinate); +else +pci_dev_lock (dev); } }
@@ -5456,8 +5458,10 @@ static void pci_bus_unlock(struct pci_bus *bus)list_for_each_entry (dev, &bus->devices, bus_list) {if (dev->subordinate)pci_bus_unlock (dev->subordinate); -pci_dev_unlock (dev); +else +pci_dev_unlock (dev); } +pci_dev_unlock (bus->self); }/* Return 1 on successful lock, 0 on contention */
@@ -5465,15 +5469,15 @@ static int pci_bus_trylock(struct pci_bus *bus) {struct pci_dev *dev; +if (!pci_dev_trylock (bus->self)) +return 0 ; +list_for_each_entry (dev, &bus->devices, bus_list) { -if (!pci_dev_trylock (dev)) - goto unlock;if (dev->subordinate) { -if (!pci_bus_trylock (dev->subordinate)) { -pci_dev_unlock (dev); +if (!pci_bus_trylock (dev->subordinate)) goto unlock; - } - } + }else if (!pci_dev_trylock (dev)) + goto unlock; }return 1 ;
@@ -5481,8 +5485,10 @@ static int pci_bus_trylock(struct pci_bus *bus)list_for_each_entry_continue_reverse (dev, &bus->devices, bus_list) {if (dev->subordinate)pci_bus_unlock (dev->subordinate); -pci_dev_unlock (dev); +else +pci_dev_unlock (dev); } +pci_dev_unlock (bus->self);return 0 ; }
@@ -5514,9 +5520,10 @@ static void pci_slot_lock(struct pci_slot *slot)list_for_each_entry (dev, &slot->bus->devices, bus_list) {if (!dev->slot || dev->slot != slot)continue ; -pci_dev_lock (dev);if (dev->subordinate)pci_bus_lock (dev->subordinate); +else +pci_dev_lock (dev); } }
@@ -5542,14 +5549,13 @@ static int pci_slot_trylock(struct pci_slot *slot)list_for_each_entry (dev, &slot->bus->devices, bus_list) {if (!dev->slot || dev->slot != slot)continue ; -if (!pci_dev_trylock (dev)) - goto unlock;if (dev->subordinate) {if (!pci_bus_trylock (dev->subordinate)) {pci_dev_unlock (dev); goto unlock; } - } + }else if (!pci_dev_trylock (dev)) + goto unlock; }return 1 ;
@@ -5560,7 +5566,8 @@ static int pci_slot_trylock(struct pci_slot *slot)continue ;if (dev->subordinate)pci_bus_unlock (dev->subordinate); -pci_dev_unlock (dev); +else +pci_dev_unlock (dev); }return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 250/375 tcp: Dont drop SYN+ACK for simultaneous connect().
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 23e89e8ee7be73e21200947885a6d3a109a2c58d ]
RFC 9293 states that in the case of simultaneous connect(), the connection gets established when SYN+ACK is received. [0]
TCP Peer A TCP Peer 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> ...
6. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
7. ... <SEQ=100><ACK=301><CTL=SYN,ACK> --> ESTABLISHED
However, since commit 0c24604b68fc ("tcp: implement RFC 5961 4.2"), such a SYN+ACK is dropped in tcp_validate_incoming() and responded with Challenge ACK.
For example, the write() syscall in the following packetdrill script fails with -EAGAIN, and wrong SNMP stats get incremented.
0 socket(..., SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP) = 3
+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
+0 > S 0:0(0) <mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 8> +0 < S 0:0(0) win 1000 <mss 1000>
+0 > S. 0:0(0) ack 1 <mss 1460,sackOK,TS val 3308134035 ecr 0,nop,wscale 8> +0 < S. 0:0(0) ack 1 win 1000
+0 write(3, ..., 100) = 100
+0 > P. 1:101(100) ack 1
--
# packetdrill cross-synack.pkt cross-synack.pkt:13: runtime error in write call: Expected result 100 but got -1 with errno 11 (Resource temporarily unavailable) # nstat ... TcpExtTCPChallengeACK 1 0.0 TcpExtTCPSYNChallenge 1 0.0
The problem is that bpf_skops_established() is triggered by the Challenge ACK instead of SYN+ACK. This causes the bpf prog to miss the chance to check if the peer supports a TCP option that is expected to be exchanged in SYN and SYN+ACK.
Let's accept a bare SYN+ACK for active-open TCP_SYN_RECV sockets to avoid such a situation.
Note that tcp_ack_snd_check() in tcp_rcv_state_process() is skipped not to send an unnecessary ACK, but this could be a bit risky for net.git, so this targets for net-next.
--- net/ipv4/tcp_input.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/ipv4/tcp_input.c +9 -0
@@ -6004,6 +6004,11 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,* RFC 5961 4.2 : Send a challenge ack */ if (th->syn) { +if (sk->sk_state ==TCP_SYN_RECV && sk->sk_socket && th->ack && +TCP_SKB_CB (skb)->seq +1 ==TCP_SKB_CB (skb)->end_seq && +TCP_SKB_CB (skb)->seq +1 == tp->rcv_nxt && +TCP_SKB_CB (skb)->ack_seq == tp->snd_nxt) + goto pass; syn_challenge:if (syn_inerr)TCP_INC_STATS (sock_net (sk),TCP_MIB_INERRS );
@@ -6013,6 +6018,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, goto discard; } +pass:bpf_skops_parse_hdr (sk, skb);return true;
@@ -6819,6 +6825,9 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)tcp_fast_path_on (tp);if (sk->sk_shutdown &SEND_SHUTDOWN )tcp_shutdown (sk,SEND_SHUTDOWN ); + +if (sk->sk_socket) + goto consume;break ;case TCP_FIN_WAIT1 : {
Signature · 1 line
2.43.0
Re: [PATCH 6.10 250/375] tcp: Dont drop SYN+ACK for simultaneous connect().
Hi Greg,
-Cc netdev devs for this issue, not to create confusions.
Quoted 1 line · Greg Kroah-Hartman
[ Upstream commit
23e89e8ee7be73e21200947885a6d3a109a2c58d]
I just noticed that your scripts stripped the simple quotes from the
subject: "Don't" -> "Dont". It's not a big issue, because the commit titles are correct in the Git tree:
The subject is also correct in the queue:
So it is only an issue in the emails, just confusing not to find this patch in lore when looking at the subject with the quote :)
Cheers,
Matt
Signature · 1 line
Sponsored by the NGI0 Core fund.
Greg Kroah-Hartman
maintainerRe: [PATCH 6.10 250/375] tcp: Dont drop SYN+ACK for simultaneous connect().
Quoted 18 lines · Matthieu Baerts
Hi Greg,
-Cc netdev devs for this issue, not to create confusions.
Quoted 1 line · Greg Kroah-Hartman
[ Upstream commit
23e89e8ee7be73e21200947885a6d3a109a2c58d]I just noticed that your scripts stripped the simple quotes from the
subject: "Don't" -> "Dont". It's not a big issue, because the commit titles are correct in the Git tree:The subject is also correct in the queue:
Quoted 8 lines
So it is only an issue in the emails, just confusing not to find this patch in lore when looking at the subject with the quote :)
Thanks for pointing it out. Given that we are taking raw patches, turning them into commits using 'git quiltimport' and then exporting them using 'quilt mail --mbox' and then splitting them apart using a perl script, it's amazing it all works at all :)
Something somewhere along the line is doing the cleanup, if I get a chance I'll try to figure it out. If you are curious, here's the horrid script that does it all if you are bored:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git/tree/scripts/quilt-mail
thanks,
greg k-h
Greg Kroah-Hartman
maintainerPATCH 251/375 Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Neeraj Sanjay Kale <[email protected]>
[ Upstream commit c68bbf5e334b35b36ac5b9f0419f1f93f796bad1 ]
This adds a check before freeing the rx->skb in flush and close functions to handle the kernel crash seen while removing driver after FW download fails or before FW download completes.
dmesg log:
[ 54.634586] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000080 [ 54.643398] Mem abort info: [ 54.646204] ESR = 0x0000000096000004 [ 54.649964] EC = 0x25: DABT (current EL), IL = 32 bits [ 54.655286] SET = 0, FnV = 0 [ 54.658348] EA = 0, S1PTW = 0 [ 54.661498] FSC = 0x04: level 0 translation fault [ 54.666391] Data abort info: [ 54.669273] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 [ 54.674768] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 54.674771] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 54.674775] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000048860000 [ 54.674780] [0000000000000080] pgd=0000000000000000, p4d=0000000000000000 [ 54.703880] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP [ 54.710152] Modules linked in: btnxpuart(-) overlay fsl_jr_uio caam_jr caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine authenc libdes crct10dif_ce polyval_ce polyval_generic snd_soc_imx_spdif snd_soc_imx_card snd_soc_ak5558 snd_soc_ak4458 caam secvio error snd_soc_fsl_micfil snd_soc_fsl_spdif snd_soc_fsl_sai snd_soc_fsl_utils imx_pcm_dma gpio_ir_recv rc_core sch_fq_codel fuse [ 54.744357] CPU: 3 PID: 72 Comm: kworker/u9:0 Not tainted 6.6.3-otbr-g128004619037 #2 [ 54.744364] Hardware name: FSL i.MX8MM EVK board (DT) [ 54.744368] Workqueue: hci0 hci_power_on [ 54.757244] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 54.757249] pc : kfree_skb_reason+0x18/0xb0 [ 54.772299] lr : btnxpuart_flush+0x40/0x58 [btnxpuart] [ 54.782921] sp : ffff8000805ebca0 [ 54.782923] x29: ffff8000805ebca0 x28: ffffa5c6cf1869c0 x27: ffffa5c6cf186000 [ 54.782931] x26: ffff377b84852400 x25: ffff377b848523c0 x24: ffff377b845e7230 [ 54.782938] x23: ffffa5c6ce8dbe08 x22: ffffa5c6ceb65410 x21: 00000000ffffff92 [ 54.782945] x20: ffffa5c6ce8dbe98 x19: ffffffffffffffac x18: ffffffffffffffff [ 54.807651] x17: 0000000000000000 x16: ffffa5c6ce2824ec x15: ffff8001005eb857 [ 54.821917] x14: 0000000000000000 x13: ffffa5c6cf1a02e0 x12: 0000000000000642 [ 54.821924] x11: 0000000000000040 x10: ffffa5c6cf19d690 x9 : ffffa5c6cf19d688 [ 54.821931] x8 : ffff377b86000028 x7 : 0000000000000000 x6 : 0000000000000000 [ 54.821938] x5 : ffff377b86000000 x4 : 0000000000000000 x3 : 0000000000000000 [ 54.843331] x2 : 0000000000000000 x1 : 0000000000000002 x0 : ffffffffffffffac [ 54.857599] Call trace: [ 54.857601] kfree_skb_reason+0x18/0xb0 [ 54.863878] btnxpuart_flush+0x40/0x58 [btnxpuart] [ 54.863888] hci_dev_open_sync+0x3a8/0xa04 [ 54.872773] hci_power_on+0x54/0x2e4 [ 54.881832] process_one_work+0x138/0x260 [ 54.881842] worker_thread+0x32c/0x438 [ 54.881847] kthread+0x118/0x11c [ 54.881853] ret_from_fork+0x10/0x20 [ 54.896406] Code: a9be7bfd 910003fd f9000bf3 aa0003f3 (b940d400) [ 54.896410] ---[ end trace 0000000000000000 ]---
--- drivers/bluetooth/btnxpuart.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/bluetooth/btnxpuart.c +8 -4
@@ -1326,8 +1326,10 @@ static int btnxpuart_close(struct hci_dev *hdev)serdev_device_close (nxpdev->serdev);skb_queue_purge (&nxpdev->txq); -kfree_skb (nxpdev->rx_skb); - nxpdev->rx_skb =NULL ; +if (!IS_ERR_OR_NULL (nxpdev->rx_skb)) { +kfree_skb (nxpdev->rx_skb); + nxpdev->rx_skb =NULL ; + }clear_bit (BTNXPUART_SERDEV_OPEN , &nxpdev->tx_state);return 0 ; }
@@ -1342,8 +1344,10 @@ static int btnxpuart_flush(struct hci_dev *hdev)cancel_work_sync (&nxpdev->tx_work); -kfree_skb (nxpdev->rx_skb); - nxpdev->rx_skb =NULL ; +if (!IS_ERR_OR_NULL (nxpdev->rx_skb)) { +kfree_skb (nxpdev->rx_skb); + nxpdev->rx_skb =NULL ; + }return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 252/375 net: dpaa: avoid on-stack arrays of NR_CPUS elements
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 555a05d84ca2c587e2d4777006e2c2fb3dfbd91d ]
The dpaa-eth driver is written for PowerPC and Arm SoCs which have 1-24 CPUs. It depends on CONFIG_NR_CPUS having a reasonably small value in Kconfig. Otherwise, there are 2 functions which allocate on-stack arrays of NR_CPUS elements, and these can quickly explode in size, leading to warnings such as:
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:3280:12: warning:
stack frame size (16664) exceeds limit (2048) in 'dpaa_eth_probe' [-Wframe-larger-than]
The problem is twofold:
- Reducing the array size to the boot-time num_possible_cpus() (rather than the compile-time NR_CPUS) creates a variable-length array, which should be avoided in the Linux kernel.
- Using NR_CPUS as an array size makes the driver blow up in stack consumption with generic, as opposed to hand-crafted, .config files.
A simple solution is to use dynamic allocation for num_possible_cpus() elements (aka a small number determined at runtime).
--- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 20 ++++++++++++++----- .../ethernet/freescale/dpaa/dpaa_ethtool.c | 10 +++++++++- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +15 -5
@@ -931,14 +931,18 @@ static inline void dpaa_setup_egress(const struct dpaa_priv *priv, } } -static void dpaa_fq_setup (struct dpaa_priv *priv, -const struct dpaa_fq_cbs *fq_cbs, -struct fman_port *tx_port) +static int dpaa_fq_setup (struct dpaa_priv *priv, +const struct dpaa_fq_cbs *fq_cbs, +struct fman_port *tx_port) {int egress_cnt =0 , conf_cnt =0 , num_portals =0 , portal_cnt =0 , cpu;const cpumask_t *affine_cpus =qman_affine_cpus (); -u16 channels[NR_CPUS ];struct dpaa_fq *fq; +u16 *channels; + + channels =kcalloc (num_possible_cpus (),sizeof (u16),GFP_KERNEL ); +if (!channels) +return -ENOMEM ;for_each_cpu_and (cpu, affine_cpus, cpu_online_mask) channels[num_portals++] =qman_affine_channel (cpu);
@@ -997,6 +1001,10 @@ static void dpaa_fq_setup(struct dpaa_priv *priv,break ; } } + +kfree (channels); + +return 0 ; } static inline int dpaa_tx_fq_to_id(const struct dpaa_priv *priv,
@@ -3416,7 +3424,9 @@ static int dpaa_eth_probe(struct platform_device *pdev)*/ dpaa_eth_add_channel (priv->channel, &pdev->dev); -dpaa_fq_setup (priv, &dpaa_fq_cbs, priv->mac_dev->port[TX ]); + err =dpaa_fq_setup (priv, &dpaa_fq_cbs, priv->mac_dev->port[TX ]); +if (err) + goto free_dpaa_bps;/* Create a congestion group for this netdev, with * dynamically-allocated CGR ID.
drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +9 -1
@@ -457,12 +457,16 @@ static int dpaa_set_coalesce(struct net_device *dev, struct netlink_ext_ack *extack) {const cpumask_t *cpus =qman_affine_cpus (); -bool needs_revert[NR_CPUS ] = {false};struct qman_portal *portal;u32 period, prev_period;u8 thresh, prev_thresh; +bool *needs_revert;int cpu, res; + needs_revert =kcalloc (num_possible_cpus (),sizeof (bool ),GFP_KERNEL ); +if (!needs_revert) +return -ENOMEM ; + period = c->rx_coalesce_usecs; thresh = c->rx_max_coalesced_frames;
@@ -485,6 +489,8 @@ static int dpaa_set_coalesce(struct net_device *dev, needs_revert[cpu] = true; } +kfree (needs_revert); +return 0 ; revert_values:
@@ -498,6 +504,8 @@ static int dpaa_set_coalesce(struct net_device *dev,qman_dqrr_set_ithresh (portal, prev_thresh); } +kfree (needs_revert); +return res; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 253/375 drm/amdgpu: add mutex to protect ras shared memory
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: YiPeng Chai <[email protected]>
[ Upstream commit b3fb79cda5688a44a423c27b791f5456d801e49c ]
Add mutex to protect ras shared memory.
v2:
Add TA_RAS_COMMAND__TRIGGER_ERROR command call status check.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 123 ++++++++++++++------- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c | 2 + 3 files changed, 86 insertions(+), 40 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +83 -40
@@ -1584,6 +1584,68 @@ static void psp_ras_ta_check_status(struct psp_context *psp) } } +static int psp_ras_send_cmd (struct psp_context *psp, +enum ras_command cmd_id,void *in,void *out) +{ +struct ta_ras_shared_memory *ras_cmd; +uint32_t cmd = cmd_id; +int ret =0 ; + +if (!in) +return -EINVAL ; + +mutex_lock (&psp->ras_context.mutex); + ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; +memset (ras_cmd,0 ,sizeof (struct ta_ras_shared_memory )); + +switch (cmd) { +case TA_RAS_COMMAND__ENABLE_FEATURES : +case TA_RAS_COMMAND__DISABLE_FEATURES : +memcpy (&ras_cmd->ras_in_message, + in,sizeof (ras_cmd->ras_in_message)); +break ; +case TA_RAS_COMMAND__TRIGGER_ERROR : +memcpy (&ras_cmd->ras_in_message.trigger_error, + in,sizeof (ras_cmd->ras_in_message.trigger_error)); +break ; +case TA_RAS_COMMAND__QUERY_ADDRESS : +memcpy (&ras_cmd->ras_in_message.address, + in,sizeof (ras_cmd->ras_in_message.address)); +break ; +default : +dev_err (psp->adev->dev,"Invalid ras cmd id: %u\n" , cmd); + ret = -EINVAL ; + goto err_out; + } + + ras_cmd->cmd_id = cmd; + ret =psp_ras_invoke (psp, ras_cmd->cmd_id); + +switch (cmd) { +case TA_RAS_COMMAND__TRIGGER_ERROR : +if (ret || psp->cmd_buf_mem->resp.status) + ret = -EINVAL ; +else if (out) +memcpy (out, &ras_cmd->ras_status,sizeof (ras_cmd->ras_status)); +break ; +case TA_RAS_COMMAND__QUERY_ADDRESS : +if (ret || ras_cmd->ras_status || psp->cmd_buf_mem->resp.status) + ret = -EINVAL ; +else if (out) +memcpy (out, + &ras_cmd->ras_out_message.address, +sizeof (ras_cmd->ras_out_message.address)); +break ; +default : +break ; + } + +err_out: +mutex_unlock (&psp->ras_context.mutex); + +return ret; +} +int psp_ras_invoke (struct psp_context *psp,uint32_t ta_cmd_id) {struct ta_ras_shared_memory *ras_cmd;
@@ -1625,23 +1687,15 @@ int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)int psp_ras_enable_features (struct psp_context *psp,union ta_ras_cmd_input *info,bool enable) { -struct ta_ras_shared_memory *ras_cmd; +enum ras_command cmd_id;int ret; -if (!psp->ras_context.context.initialized) +if (!psp->ras_context.context.initialized || !info)return -EINVAL ; - ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; -memset (ras_cmd,0 ,sizeof (struct ta_ras_shared_memory )); - -if (enable) - ras_cmd->cmd_id =TA_RAS_COMMAND__ENABLE_FEATURES ; -else - ras_cmd->cmd_id =TA_RAS_COMMAND__DISABLE_FEATURES ; - - ras_cmd->ras_in_message = *info; - - ret =psp_ras_invoke (psp, ras_cmd->cmd_id); + cmd_id = enable ? +TA_RAS_COMMAND__ENABLE_FEATURES :TA_RAS_COMMAND__DISABLE_FEATURES ; + ret =psp_ras_send_cmd (psp, cmd_id, info,NULL );if (ret)return -EINVAL ;
@@ -1665,6 +1719,8 @@ int psp_ras_terminate(struct psp_context *psp) psp->ras_context.context.initialized = false; +mutex_destroy (&psp->ras_context.mutex); +return ret; }
@@ -1749,9 +1805,10 @@ int psp_ras_initialize(struct psp_context *psp) ret =psp_ta_load (psp, &psp->ras_context.context); -if (!ret && !ras_cmd->ras_status) +if (!ret && !ras_cmd->ras_status) { psp->ras_context.context.initialized = true; -else { +mutex_init (&psp->ras_context.mutex); + }else {if (ras_cmd->ras_status)dev_warn (adev->dev,"RAS Init Status: 0x%X\n" , ras_cmd->ras_status);
@@ -1765,12 +1822,12 @@ int psp_ras_initialize(struct psp_context *psp)int psp_ras_trigger_error (struct psp_context *psp,struct ta_ras_trigger_error_input *info,uint32_t instance_mask) { -struct ta_ras_shared_memory *ras_cmd;struct amdgpu_device *adev = psp->adev;int ret;uint32_t dev_mask; +uint32_t ras_status =0 ; -if (!psp->ras_context.context.initialized) +if (!psp->ras_context.context.initialized || !info)return -EINVAL ;switch (info->block_id) {
@@ -1794,13 +1851,8 @@ int psp_ras_trigger_error(struct psp_context *psp, dev_mask &=AMDGPU_RAS_INST_MASK ; info->sub_block_index |= dev_mask; - ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; -memset (ras_cmd,0 ,sizeof (struct ta_ras_shared_memory )); - - ras_cmd->cmd_id =TA_RAS_COMMAND__TRIGGER_ERROR ; - ras_cmd->ras_in_message.trigger_error = *info; - - ret =psp_ras_invoke (psp, ras_cmd->cmd_id); + ret =psp_ras_send_cmd (psp, +TA_RAS_COMMAND__TRIGGER_ERROR , info, &ras_status);if (ret)return -EINVAL ;
@@ -1810,9 +1862,9 @@ int psp_ras_trigger_error(struct psp_context *psp,if (amdgpu_ras_intr_triggered ())return 0 ; -if (ras_cmd->ras_status ==TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED ) +if (ras_status ==TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED )return -EACCES ; -else if (ras_cmd->ras_status) +else if (ras_status)return -EINVAL ;return 0 ;
@@ -1822,25 +1874,16 @@ int psp_ras_query_address(struct psp_context *psp,struct ta_ras_query_address_input *addr_in, struct ta_ras_query_address_output *addr_out) { - struct ta_ras_shared_memory *ras_cmd; int ret; -if (!psp->ras_context.context.initialized) -return -EINVAL ; - - ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf; -memset (ras_cmd,0 ,sizeof (struct ta_ras_shared_memory )); - - ras_cmd->cmd_id =TA_RAS_COMMAND__QUERY_ADDRESS ; - ras_cmd->ras_in_message.address = *addr_in; - - ret =psp_ras_invoke (psp, ras_cmd->cmd_id); -if (ret || ras_cmd->ras_status || psp->cmd_buf_mem->resp.status) +if (!psp->ras_context.context.initialized || + !addr_in || !addr_out)return -EINVAL ; - *addr_out = ras_cmd->ras_out_message.address; + ret =psp_ras_send_cmd (psp, +TA_RAS_COMMAND__QUERY_ADDRESS , addr_in, addr_out); -return 0 ; +return ret; }// ras end
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +1 -0
@@ -200,6 +200,7 @@ struct psp_xgmi_context {struct psp_ras_context {struct ta_context context;struct amdgpu_ras *ras; +struct mutex mutex; };#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c +2 -0
@@ -351,6 +351,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size context->session_id = ta_id; +mutex_lock (&psp->ras_context.mutex); ret =prep_ta_mem_context (&context->mem_context, shared_buf, shared_buf_len);if (ret) goto err_free_shared_buf;
@@ -369,6 +370,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size ret = -EFAULT ; err_free_shared_buf: +mutex_unlock (&psp->ras_context.mutex);kfree (shared_buf);return ret;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 254/375 LoongArch: Use correct API to map cmdline in relocate_kernel()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <[email protected]>
[ Upstream commit 0124fbb4c6dba23dbdf80c829be68adbccde2722 ]
fw_arg1 is in memory space rather than I/O space, so we should use early_memremap_ro() instead of early_ioremap() to map the cmdline. Moreover, we should unmap it after using.
--- arch/loongarch/kernel/relocate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/loongarch/kernel/relocate.c +3 -1
@@ -13,6 +13,7 @@#include <asm/bootinfo.h> #include <asm/early_ioremap.h> #include <asm/inst.h> +#include <asm/io.h> #include <asm/sections.h> #include <asm/setup.h>
@@ -170,7 +171,7 @@ unsigned long __init relocate_kernel(void)unsigned long kernel_length;unsigned long random_offset =0 ;void *location_new = _text;/* Default to original kernel start */ -char *cmdline =early_ioremap (fw_arg1,COMMAND_LINE_SIZE );/* Boot command line is passed in fw_arg1 */ +char *cmdline =early_memremap_ro (fw_arg1,COMMAND_LINE_SIZE );/* Boot command line is passed in fw_arg1 */ strscpy (boot_command_line, cmdline,COMMAND_LINE_SIZE );
@@ -182,6 +183,7 @@ unsigned long __init relocate_kernel(void) random_offset = (unsigned long )location_new - (unsigned long )(_text);#endif reloc_offset = (unsigned long )_text -VMLINUX_LOAD_ADDRESS ; +early_memunmap (cmdline,COMMAND_LINE_SIZE );if (random_offset) { kernel_length = (long )(_end) - (long )(_text);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 255/375 regmap: maple: work around gcc-14.1 false-positive warning
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit 542440fd7b30983cae23e32bd22f69a076ec7ef4 ]
With gcc-14.1, there is a false-postive -Wuninitialized warning in regcache_maple_drop:
drivers/base/regmap/regcache-maple.c: In function 'regcache_maple_drop':drivers/base/regmap/regcache-maple.c:113:23: error: 'lower_index' is used uninitialized [-Werror=uninitialized]
113 | unsigned long lower_index, lower_last;
| ^~~~~~~~~~~drivers/base/regmap/regcache-maple.c:113:36: error: 'lower_last' is used uninitialized [-Werror=uninitialized]
113 | unsigned long lower_index, lower_last;
| ^~~~~~~~~~
I've created a reduced test case to see if this needs to be reported as a gcc, but it appears that the gcc-14.x branch already has a change that turns this into a more sensible -Wmaybe-uninitialized warning, so I ended up not reporting it so far.
The reduced test case also produces a warning for gcc-13 and gcc-12 but I don't see that with the version in the kernel.
--- drivers/base/regmap/regcache-maple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/base/regmap/regcache-maple.c +2 -1
@@ -110,7 +110,8 @@ static int regcache_maple_drop(struct regmap *map, unsigned int min,struct maple_tree *mt = map->cache;MA_STATE (mas, mt, min, max);unsigned long *entry, *lower, *upper; -unsigned long lower_index, lower_last; +/* initialized to work around false-positive -Wuninitialized warning */ +unsigned long lower_index =0 , lower_last =0 ;unsigned long upper_index, upper_last;int ret =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 256/375 s390/boot: Do not assume the decompressor range is reserved
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Gordeev <[email protected]>
[ Upstream commit b798b685b42c9dbe508e59a74250d97c41bec35e ]
When allocating a random memory range for .amode31 sections the minimal randomization address is 0. That does not lead to a possible overlap with the decompressor image (which also starts from 0) since by that time the image range is already reserved.
Do not assume the decompressor range is reserved and always provide the minimal randomization address for .amode31 sections beyond the decompressor. That is a prerequisite for moving the lowcore memory address from NULL elsewhere.
--- arch/s390/boot/startup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/s390/boot/startup.c +6 -2
@@ -476,8 +476,12 @@ void startup_kernel(void)* before the kernel started. Therefore, in case the two sections * overlap there is no risk of corrupting any data. */ -if (kaslr_enabled ()) - amode31_lma =randomize_within_range (vmlinux.amode31_size,PAGE_SIZE ,0 ,SZ_2G ); +if (kaslr_enabled ()) { +unsigned long amode31_min; + + amode31_min = (unsigned long )_decompressor_end; + amode31_lma =randomize_within_range (vmlinux.amode31_size,PAGE_SIZE , amode31_min,SZ_2G ); + }if (!amode31_lma) amode31_lma = text_lma - vmlinux.amode31_size;physmem_reserve (RR_AMODE31 , amode31_lma, vmlinux.amode31_size);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 257/375 cachefiles: Set the max subreq size for cache writes to MAX_RW_COUNT
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 51d37982bbac3ea0ca21b2797a9cb0044272b3aa ]
Set the maximum size of a subrequest that writes to cachefiles to be MAX_RW_COUNT so that we don't overrun the maximum write we can make to the backing filesystem.
--- fs/cachefiles/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cachefiles/io.c +1 -1
@@ -630,7 +630,7 @@ static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)_enter ("W=%x[%x] %llx" , wreq->debug_id, subreq->debug_index, subreq->start); - subreq->max_len =ULONG_MAX ; + subreq->max_len =MAX_RW_COUNT ; subreq->max_nr_segs =BIO_MAX_VECS ;if (!cachefiles_cres_file (cres)) {
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 258/375 vfs: Fix potential circular locking through setxattr() and removexattr()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit c3a5e3e872f3688ae0dc57bb78ca633921d96a91 ]
When using cachefiles, lockdep may emit something similar to the circular locking dependency notice below. The problem appears to stem from the following:
(1) Cachefiles manipulates xattrs on the files in its cache when called
from ->writepages().
(2) The setxattr() and removexattr() system call handlers get the name (and value) from userspace after taking the sb_writers lock, putting accesses of the vma->vm_lock and mm->mmap_lock inside of that.
(3) The afs filesystem uses a per-inode lock to prevent multiple revalidation RPCs and in writeback vs truncate to prevent parallel operations from deadlocking against the server on one side and local page locks on the other.
Fix this by moving the getting of the name and value in {get,remove}xattr() outside of the sb_writers lock. This also has the minor benefits that we don't need to reget these in the event of a retry and we never try to take the sb_writers lock in the event we can't pull the name and value into the kernel.
Alternative approaches that might fix this include moving the dispatch of a write to the cache off to a workqueue or trying to do without the validation lock in afs. Note that this might also affect other filesystems that use netfslib and/or cachefiles.
======================================================
WARNING: possible circular locking dependency detected
6.10.0-build2+ #956 Not tainted
------------------------------------------------------
fsstress/6050 is trying to acquire lock:
ffff888138fd82f0 (mapping.invalidate_lock#3){++++}-{3:3}, at: filemap_fault+0x26e/0x8b0
but task is already holding lock:
ffff888113f26d18 (&vma->vm_lock->lock){++++}-{3:3}, at: lock_vma_under_rcu+0x165/0x250
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #4 (&vma->vm_lock->lock){++++}-{3:3}:
__lock_acquire+0xaf0/0xd80
lock_acquire.part.0+0x103/0x280
down_write+0x3b/0x50
vma_start_write+0x6b/0xa0
vma_link+0xcc/0x140
insert_vm_struct+0xb7/0xf0
alloc_bprm+0x2c1/0x390
kernel_execve+0x65/0x1a0
call_usermodehelper_exec_async+0x14d/0x190
ret_from_fork+0x24/0x40
ret_from_fork_asm+0x1a/0x30-> #3 (&mm->mmap_lock){++++}-{3:3}:
__lock_acquire+0xaf0/0xd80
lock_acquire.part.0+0x103/0x280
__might_fault+0x7c/0xb0
strncpy_from_user+0x25/0x160
removexattr+0x7f/0x100
__do_sys_fremovexattr+0x7e/0xb0
do_syscall_64+0x9f/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #2 (sb_writers#14){.+.+}-{0:0}:
__lock_acquire+0xaf0/0xd80
lock_acquire.part.0+0x103/0x280
percpu_down_read+0x3c/0x90
vfs_iocb_iter_write+0xe9/0x1d0
__cachefiles_write+0x367/0x430
cachefiles_issue_write+0x299/0x2f0
netfs_advance_write+0x117/0x140
netfs_write_folio.isra.0+0x5ca/0x6e0
netfs_writepages+0x230/0x2f0
afs_writepages+0x4d/0x70
do_writepages+0x1e8/0x3e0
filemap_fdatawrite_wbc+0x84/0xa0
__filemap_fdatawrite_range+0xa8/0xf0
file_write_and_wait_range+0x59/0x90
afs_release+0x10f/0x270
__fput+0x25f/0x3d0
__do_sys_close+0x43/0x70
do_syscall_64+0x9f/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #1 (&vnode->validate_lock){++++}-{3:3}:
__lock_acquire+0xaf0/0xd80
lock_acquire.part.0+0x103/0x280
down_read+0x95/0x200
afs_writepages+0x37/0x70
do_writepages+0x1e8/0x3e0
filemap_fdatawrite_wbc+0x84/0xa0
filemap_invalidate_inode+0x167/0x1e0
netfs_unbuffered_write_iter+0x1bd/0x2d0
vfs_write+0x22e/0x320
ksys_write+0xbc/0x130
do_syscall_64+0x9f/0x100
entry_SYSCALL_64_after_hwframe+0x76/0x7e-> #0 (mapping.invalidate_lock#3){++++}-{3:3}:
check_noncircular+0x119/0x160
check_prev_add+0x195/0x430
__lock_acquire+0xaf0/0xd80
lock_acquire.part.0+0x103/0x280
down_read+0x95/0x200
filemap_fault+0x26e/0x8b0
__do_fault+0x57/0xd0
do_pte_missing+0x23b/0x320
__handle_mm_fault+0x2d4/0x320
handle_mm_fault+0x14f/0x260
do_user_addr_fault+0x2a2/0x500
exc_page_fault+0x71/0x90
asm_exc_page_fault+0x22/0x30other info that might help us debug this:
Chain exists of: mapping.invalidate_lock#3 --> &mm->mmap_lock --> &vma->vm_lock->lock Possible unsafe locking scenario:
CPU0 CPU1
---- ----
rlock(&vma->vm_lock->lock);
lock(&mm->mmap_lock);
lock(&vma->vm_lock->lock); rlock(mapping.invalidate_lock#3);
*** DEADLOCK ***
1 lock held by fsstress/6050:
#0: ffff888113f26d18 (&vma->vm_lock->lock){++++}-{3:3}, at: lock_vma_under_rcu+0x165/0x250
stack backtrace: CPU: 0 PID: 6050 Comm: fsstress Not tainted 6.10.0-build2+ #956 Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014 Call Trace: <TASK> dump_stack_lvl+0x57/0x80 check_noncircular+0x119/0x160 ? queued_spin_lock_slowpath+0x4be/0x510 ? __pfx_check_noncircular+0x10/0x10 ? __pfx_queued_spin_lock_slowpath+0x10/0x10 ? mark_lock+0x47/0x160 ? init_chain_block+0x9c/0xc0 ? add_chain_block+0x84/0xf0 check_prev_add+0x195/0x430 __lock_acquire+0xaf0/0xd80 ? __pfx___lock_acquire+0x10/0x10 ? __lock_release.isra.0+0x13b/0x230 lock_acquire.part.0+0x103/0x280 ? filemap_fault+0x26e/0x8b0 ? __pfx_lock_acquire.part.0+0x10/0x10 ? rcu_is_watching+0x34/0x60 ? lock_acquire+0xd7/0x120 down_read+0x95/0x200 ? filemap_fault+0x26e/0x8b0 ? __pfx_down_read+0x10/0x10 ? __filemap_get_folio+0x25/0x1a0 filemap_fault+0x26e/0x8b0 ? __pfx_filemap_fault+0x10/0x10 ? find_held_lock+0x7c/0x90 ? __pfx___lock_release.isra.0+0x10/0x10 ? __pte_offset_map+0x99/0x110 __do_fault+0x57/0xd0 do_pte_missing+0x23b/0x320 __handle_mm_fault+0x2d4/0x320 ? __pfx___handle_mm_fault+0x10/0x10 handle_mm_fault+0x14f/0x260 do_user_addr_fault+0x2a2/0x500 exc_page_fault+0x71/0x90 asm_exc_page_fault+0x22/0x30
--- fs/xattr.c | 91 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 43 deletions(-)
fs/xattr.c +48 -43
@@ -630,10 +630,9 @@ int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry, ctx->kvalue, ctx->size, ctx->flags); } -static long -setxattr (struct mnt_idmap *idmap,struct dentry *d, -const char __user *name,const void __user *value,size_t size, -int flags) +static int path_setxattr (const char __user *pathname, +const char __user *name,const void __user *value, +size_t size,int flags,unsigned int lookup_flags) {struct xattr_name kname;struct xattr_ctx ctx = {
@@ -643,33 +642,20 @@ setxattr(struct mnt_idmap *idmap, struct dentry *d, .kname = &kname, .flags = flags, }; +struct path path;int error; error =setxattr_copy (name, &ctx);if (error)return error; - error =do_setxattr (idmap, d, &ctx); - -kvfree (ctx.kvalue); -return error; -} - -static int path_setxattr (const char __user *pathname, -const char __user *name,const void __user *value, -size_t size,int flags,unsigned int lookup_flags) -{ -struct path path; -int error; - retry: error =user_path_at (AT_FDCWD , pathname, lookup_flags, &path);if (error) -return error; + goto out; error =mnt_want_write (path.mnt);if (!error) { - error =setxattr (mnt_idmap (path.mnt), path.dentry, name, - value, size, flags); + error =do_setxattr (mnt_idmap (path.mnt), path.dentry, &ctx);mnt_drop_write (path.mnt); }path_put (&path);
@@ -677,6 +663,9 @@ static int path_setxattr(const char __user *pathname, lookup_flags |=LOOKUP_REVAL ; goto retry; } + +out: +kvfree (ctx.kvalue);return error; }
@@ -697,20 +686,32 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, const void __user *,value, size_t, size, int, flags) { -struct fd f =fdget (fd); -int error = -EBADF ; +struct xattr_name kname; +struct xattr_ctx ctx = { + .cvalue = value, + .kvalue =NULL , + .size = size, + .kname = &kname, + .flags = flags, + }; +int error; +CLASS (fd, f)(fd);if (!f.file) -return error; +return -EBADF ; +audit_file (f.file); + error =setxattr_copy (name, &ctx); +if (error) +return error; + error =mnt_want_write_file (f.file);if (!error) { - error =setxattr (file_mnt_idmap (f.file), - f.file->f_path.dentry, name, - value, size, flags); + error =do_setxattr (file_mnt_idmap (f.file), + f.file->f_path.dentry, &ctx);mnt_drop_write_file (f.file); } -fdput (f); +kvfree (ctx.kvalue);return error; }
@@ -899,9 +900,17 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)* Extended attribute REMOVE operations */ static long -removexattr (struct mnt_idmap *idmap,struct dentry *d, -const char __user *name) +removexattr (struct mnt_idmap *idmap,struct dentry *d,const char *name) { +if (is_posix_acl_xattr (name)) +return vfs_remove_acl (idmap, d, name); +return vfs_removexattr (idmap, d, name); +} + +static int path_removexattr (const char __user *pathname, +const char __user *name,unsigned int lookup_flags) +{ +struct path path;int error;char kname[XATTR_NAME_MAX +1 ];
@@ -910,25 +919,13 @@ removexattr(struct mnt_idmap *idmap, struct dentry *d, error = -ERANGE ;if (error <0 )return error; - -if (is_posix_acl_xattr (kname)) -return vfs_remove_acl (idmap, d, kname); - -return vfs_removexattr (idmap, d, kname); -} - -static int path_removexattr (const char __user *pathname, -const char __user *name,unsigned int lookup_flags) -{ -struct path path; -int error; retry: error =user_path_at (AT_FDCWD , pathname, lookup_flags, &path);if (error)return error; error =mnt_want_write (path.mnt);if (!error) { - error =removexattr (mnt_idmap (path.mnt), path.dentry, name); + error =removexattr (mnt_idmap (path.mnt), path.dentry, kname);mnt_drop_write (path.mnt); }path_put (&path);
@@ -954,15 +951,23 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) {struct fd f =fdget (fd); +char kname[XATTR_NAME_MAX +1 ];int error = -EBADF ;if (!f.file)return error;audit_file (f.file); + + error =strncpy_from_user (kname, name,sizeof (kname)); +if (error ==0 || error ==sizeof (kname)) + error = -ERANGE ; +if (error <0 ) +return error; + error =mnt_want_write_file (f.file);if (!error) { error =removexattr (file_mnt_idmap (f.file), - f.file->f_path.dentry, name); + f.file->f_path.dentry, kname);mnt_drop_write_file (f.file); }fdput (f);
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 259/375 i3c: master: svc: resend target address when get NACK
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Li <[email protected]>
[ Upstream commit 9bc7501b0b90f4d0c34b97c14ff1f708ce7ad8f3 ]
According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3:
If the Controller chooses to start an I3C Message with an I3C Dynamic Address, then special provisions shall be made because that same I3C Target may be initiating an IBI or a Controller Role Request. So, one of three things may happen: (skip 1, 2)
3. The Addresses match and the RnW bits also match, and so neither Controller nor Target will ACK since both are expecting the other side to provide ACK. As a result, each side might think it had "won" arbitration, but neither side would continue, as each would subsequently see that the other did not provide ACK.
...
For either value of RnW: Due to the NACK, the Controller shall defer the Private Write or Private Read, and should typically transmit the Target
^^^^^^^^^^^^^^^^^^^
Address again after a Repeated START (i.e., the next one or any one prior ^^^^^^^^^^^^^
to a STOP in the Frame). Since the Address Header following a Repeated START is not arbitrated, the Controller will always win (see Section 5.1.2.2.4).
Resend target address again if address is not 7E and controller get NACK.
--- drivers/i3c/master/svc-i3c-master.c | 58 ++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 14 deletions(-)
drivers/i3c/master/svc-i3c-master.c +44 -14
@@ -1052,29 +1052,59 @@ static int svc_i3c_master_xfer(struct svc_i3c_master *master, u8 *in, const u8 *out, unsigned int xfer_len, unsigned int *actual_len, bool continued) { + int retry = 2;u32 reg;int ret;/* clean SVC_I3C_MINT_IBIWON w1c bits */ writel (SVC_I3C_MINT_IBIWON , master->regs +SVC_I3C_MSTATUS ); -writel (SVC_I3C_MCTRL_REQUEST_START_ADDR | - xfer_type | -SVC_I3C_MCTRL_IBIRESP_NACK | -SVC_I3C_MCTRL_DIR (rnw) | -SVC_I3C_MCTRL_ADDR (addr) | -SVC_I3C_MCTRL_RDTERM (*actual_len), - master->regs +SVC_I3C_MCTRL ); - ret =readl_poll_timeout (master->regs +SVC_I3C_MSTATUS , reg, +while (retry--) { +writel (SVC_I3C_MCTRL_REQUEST_START_ADDR | + xfer_type | +SVC_I3C_MCTRL_IBIRESP_NACK | +SVC_I3C_MCTRL_DIR (rnw) | +SVC_I3C_MCTRL_ADDR (addr) | +SVC_I3C_MCTRL_RDTERM (*actual_len), + master->regs +SVC_I3C_MCTRL ); + + ret =readl_poll_timeout (master->regs +SVC_I3C_MSTATUS , reg,SVC_I3C_MSTATUS_MCTRLDONE (reg),0 ,1000 ); -if (ret) - goto emit_stop; +if (ret) + goto emit_stop; -if (readl (master->regs +SVC_I3C_MERRWARN ) &SVC_I3C_MERRWARN_NACK ) { - ret = -ENXIO ; - *actual_len =0 ; - goto emit_stop; +if (readl (master->regs +SVC_I3C_MERRWARN ) &SVC_I3C_MERRWARN_NACK ) { +/* +* According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3. +* If the Controller chooses to start an I3C Message with an I3C Dynamic +* Address, then special provisions shall be made because that same I3C +* Target may be initiating an IBI or a Controller Role Request. So, one of +* three things may happen: (skip 1, 2) +* +* 3. The Addresses match and the RnW bits also match, and so neither +* Controller nor Target will ACK since both are expecting the other side to +* provide ACK. As a result, each side might think it had "won" arbitration, +* but neither side would continue, as each would subsequently see that the +* other did not provide ACK. +* ... +* For either value of RnW: Due to the NACK, the Controller shall defer the +* Private Write or Private Read, and should typically transmit the Target +* Address again after a Repeated START (i.e., the next one or any one prior +* to a STOP in the Frame). Since the Address Header following a Repeated +* START is not arbitrated, the Controller will always win (see Section +* 5.1.2.2.4). +*/ +if (retry && addr !=0x7e ) { +writel (SVC_I3C_MERRWARN_NACK , master->regs +SVC_I3C_MERRWARN ); + }else { + ret = -ENXIO ; + *actual_len =0 ; + goto emit_stop; + } + }else { +break ; + } }/*
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 260/375 i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Nikula <[email protected]>
[ Upstream commit 8a2be2f1db268ec735419e53ef04ca039fc027dc ]
Definitely condition dma_get_cache_alignment * defined value > 256 during driver initialization is not reason to BUG_ON(). Turn that to graceful error out with -EINVAL.
--- drivers/i3c/master/mipi-i3c-hci/dma.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i3c/master/mipi-i3c-hci/dma.c +4 -1
@@ -294,7 +294,10 @@ static int hci_dma_init(struct i3c_hci *hci) rh->ibi_chunk_sz =dma_get_cache_alignment (); rh->ibi_chunk_sz *=IBI_CHUNK_CACHELINES ; -BUG_ON (rh->ibi_chunk_sz >256 ); +if (rh->ibi_chunk_sz >256 ) { + ret = -EINVAL ; + goto err_out; + } ibi_status_ring_sz = rh->ibi_status_sz * rh->ibi_status_entries; ibi_data_ring_sz = rh->ibi_chunk_sz * rh->ibi_chunks_total;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 261/375 kselftests: dmabuf-heaps: Ensure the driver name is null-terminated
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenghui Yu <[email protected]>
[ Upstream commit 291e4baf70019f17a81b7b47aeb186b27d222159 ]
Even if a vgem device is configured in, we will skip the import_vgem_fd() test almost every time.
TAP version 13
1..11
# Testing heap: system
# =======================================
# Testing allocation and importing:
ok 1 # SKIP Could not open vgem -1
The problem is that we use the DRM_IOCTL_VERSION ioctl to query the driver version information but leave the name field a non-null-terminated string. Terminate it properly to actually test against the vgem device.
While at it, let's check the length of the driver name is exactly 4 bytes and return early otherwise (in case there is a name like "vgemfoo" that gets converted to "vgem\0" unexpectedly).
--- tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c +3 -1
@@ -29,9 +29,11 @@ static int check_vgem(int fd) version.name = name; ret =ioctl (fd,DRM_IOCTL_VERSION , &version); -if (ret) +if (ret || version.name_len !=4 )return 0 ; + name[4 ] ='\0' ; +return !strcmp (name,"vgem" ); }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 262/375 spi: hisi-kunpeng: Add verification for the max_frequency provided by the firmware
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devyn Liu <[email protected]>
[ Upstream commit 5127c42c77de18651aa9e8e0a3ced190103b449c ]
If the value of max_speed_hz is 0, it may cause a division by zero error in hisi_calc_effective_speed().
The value of max_speed_hz is provided by firmware.
Firmware is generally considered as a trusted domain. However, as division by zero errors can cause system failure, for defense measure, the value of max_speed is validated here. So 0 is regarded as invalid and an error code is returned.
--- drivers/spi/spi-hisi-kunpeng.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/spi/spi-hisi-kunpeng.c +3 -0
@@ -481,6 +481,9 @@ static int hisi_spi_probe(struct platform_device *pdev)return -EINVAL ; } +if (host->max_speed_hz ==0 ) +return dev_err_probe (dev, -EINVAL ,"spi-max-frequency can't be 0\n" ); + ret =device_property_read_u16 (dev,"num-cs" , &host->num_chipselect);if (ret)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 263/375 btrfs: initialize location to fix -Wmaybe-uninitialized in btrfs_lookup_dentry()
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba <[email protected]>
[ Upstream commit b8e947e9f64cac9df85a07672b658df5b2bcff07 ]
Some arch + compiler combinations report a potentially unused variable location in btrfs_lookup_dentry(). This is a false alert as the variable is passed by value and always valid or there's an error. The compilers cannot probably reason about that although btrfs_inode_by_name() is in the same file.
Quoted 1 line
+ /kisskb/src/fs/btrfs/inode.c: error: 'location.objectid' may be used
+uninitialized in this function [-Werror=maybe-uninitialized]: => 5603:9
Quoted 1 line
+ /kisskb/src/fs/btrfs/inode.c: error: 'location.type' may be used
+uninitialized in this function [-Werror=maybe-uninitialized]: => 5674:5
m68k-gcc8/m68k-allmodconfig
mips-gcc8/mips-allmodconfig
powerpc-gcc5/powerpc-all{mod,yes}config
powerpc-gcc5/ppc64_defconfig
Initialize it to zero, this should fix the warnings and won't change the behaviour as btrfs_inode_by_name() accepts only a root or inode item types, otherwise returns an error.
--- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/inode.c +1 -1
@@ -5699,7 +5699,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)struct inode *inode;struct btrfs_root *root =BTRFS_I (dir)->root;struct btrfs_root *sub_root = root; -struct btrfs_key location; +struct btrfs_key location = {0 };u8 di_type =0 ;int ret =0 ;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 264/375 s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <[email protected]>
[ Upstream commit 75c10d5377d8821efafed32e4d72068d9c1f8ec0 ]
The .data.rel.ro and .got section were added between the rodata and ro_after_init data section, which adds an RW mapping in between all RO mapping of the kernel image:
---[ Kernel Image Start ]---
0x000003ffe0000000-0x000003ffe0e00000 14M PMD RO X
0x000003ffe0e00000-0x000003ffe0ec7000 796K PTE RO X
0x000003ffe0ec7000-0x000003ffe0f00000 228K PTE RO NX
0x000003ffe0f00000-0x000003ffe1300000 4M PMD RO NX
0x000003ffe1300000-0x000003ffe1331000 196K PTE RO NX 0x000003ffe1331000-0x000003ffe13b3000 520K PTE RW NX <--- 0x000003ffe13b3000-0x000003ffe13d5000 136K PTE RO NX 0x000003ffe13d5000-0x000003ffe1400000 172K PTE RW NX 0x000003ffe1400000-0x000003ffe1500000 1M PMD RW NX 0x000003ffe1500000-0x000003ffe1700000 2M PTE RW NX 0x000003ffe1700000-0x000003ffe1800000 1M PMD RW NX
0x000003ffe1800000-0x000003ffe187e000 504K PTE RW NX
---[ Kernel Image End ]---
Move the ro_after_init data section again right behind the rodata section to prevent interleaving RO and RW mappings:
---[ Kernel Image Start ]---
0x000003ffe0000000-0x000003ffe0e00000 14M PMD RO X
0x000003ffe0e00000-0x000003ffe0ec7000 796K PTE RO X
0x000003ffe0ec7000-0x000003ffe0f00000 228K PTE RO NX
0x000003ffe0f00000-0x000003ffe1300000 4M PMD RO NX
0x000003ffe1300000-0x000003ffe1353000 332K PTE RO NX
0x000003ffe1353000-0x000003ffe1400000 692K PTE RW NX
0x000003ffe1400000-0x000003ffe1500000 1M PMD RW NX 0x000003ffe1500000-0x000003ffe1700000 2M PTE RW NX 0x000003ffe1700000-0x000003ffe1800000 1M PMD RW NX
0x000003ffe1800000-0x000003ffe187e000 504K PTE RW NX
---[ Kernel Image End ]---
--- arch/s390/kernel/vmlinux.lds.S | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
arch/s390/kernel/vmlinux.lds.S +9 -8
@@ -59,14 +59,6 @@ SECTIONS } :text = 0x0700 RO_DATA(PAGE_SIZE) - .data.rel.ro : { - *(.data.rel.ro .data.rel.ro.*) - } - .got : { - __got_start = .; - *(.got) - __got_end = .; - } . = ALIGN(PAGE_SIZE); _sdata = .; /* Start of data section */
@@ -80,6 +72,15 @@ SECTIONS . = ALIGN(PAGE_SIZE); __end_ro_after_init = .; + .data.rel.ro : { + *(.data.rel.ro .data.rel.ro.*) + } + .got : { + __got_start = .; + *(.got) + __got_end = .; + } + RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE) .data.rel : { *(.data.rel*)
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 265/375 HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Camila Alvarez <[email protected]>
[ Upstream commit a6e9c391d45b5865b61e569146304cff72821a5d ]
report_fixup for the Cougar 500k Gaming Keyboard was not verifying that the report descriptor size was correct before accessing it
--- drivers/hid/hid-cougar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/hid-cougar.c +1 -1
@@ -106,7 +106,7 @@ static void cougar_fix_g6_mapping(void)static __u8 *cougar_report_fixup (struct hid_device *hdev,__u8 *rdesc,unsigned int *rsize) { -if (rdesc[2 ] ==0x09 && rdesc[3 ] ==0x02 && +if (*rsize >=117 && rdesc[2 ] ==0x09 && rdesc[3 ] ==0x02 && (rdesc[115 ] | rdesc[116 ] <<8 ) >=HID_MAX_USAGES ) {hid_info (hdev,"usage count exceeds max: fixing up report descriptor\n" );
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 266/375 HID: amd_sfh: free driver_data after destroying hid device
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olivier Sobrie <[email protected]>
[ Upstream commit 97155021ae17b86985121b33cf8098bcde00d497 ]
HID driver callbacks aren't called anymore once hid_destroy_device() has been called. Hence, hid driver_data should be freed only after the hid_destroy_device() function returned as driver_data is used in several callbacks.
I observed a crash with kernel 6.10.0 on my T14s Gen 3, after enabling KASAN to debug memory allocation, I got this output:
[ 13.050438] ================================================================== [ 13.054060] BUG: KASAN: slab-use-after-free in amd_sfh_get_report+0x3ec/0x530 [amd_sfh] [ 13.054809] psmouse serio1: trackpoint: Synaptics TrackPoint firmware: 0x02, buttons: 3/3 [ 13.056432] Read of size 8 at addr ffff88813152f408 by task (udev-worker)/479
[ 13.060970] CPU: 5 PID: 479 Comm: (udev-worker) Not tainted 6.10.0-arch1-2 #1 893bb55d7f0073f25c46adbb49eb3785fefd74b0 [ 13.063978] Hardware name: LENOVO 21CQCTO1WW/21CQCTO1WW, BIOS R22ET70W (1.40 ) 03/21/2024 [ 13.067860] Call Trace: [ 13.069383] input: TPPS/2 Synaptics TrackPoint as /devices/platform/i8042/serio1/input/input8 [ 13.071486] <TASK> [ 13.071492] dump_stack_lvl+0x5d/0x80 [ 13.074870] snd_hda_intel 0000:33:00.6: enabling device (0000 -> 0002) [ 13.078296] ? amd_sfh_get_report+0x3ec/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.082199] print_report+0x174/0x505 [ 13.085776] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 13.089367] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.093255] ? amd_sfh_get_report+0x3ec/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.097464] kasan_report+0xc8/0x150 [ 13.101461] ? amd_sfh_get_report+0x3ec/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.105802] amd_sfh_get_report+0x3ec/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.110303] amdtp_hid_request+0xb8/0x110 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.114879] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.119450] sensor_hub_get_feature+0x1d3/0x540 [hid_sensor_hub 3f13be3016ff415bea03008d45d99da837ee3082] [ 13.124097] hid_sensor_parse_common_attributes+0x4d0/0xad0 [hid_sensor_iio_common c3a5cbe93969c28b122609768bbe23efe52eb8f5] [ 13.127404] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.131925] ? __pfx_hid_sensor_parse_common_attributes+0x10/0x10 [hid_sensor_iio_common c3a5cbe93969c28b122609768bbe23efe52eb8f5] [ 13.136455] ? _raw_spin_lock_irqsave+0x96/0xf0 [ 13.140197] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 13.143602] ? devm_iio_device_alloc+0x34/0x50 [industrialio 3d261d5e5765625d2b052be40e526d62b1d2123b] [ 13.147234] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.150446] ? __devm_add_action+0x167/0x1d0 [ 13.155061] hid_gyro_3d_probe+0x120/0x7f0 [hid_sensor_gyro_3d 63da36a143b775846ab2dbb86c343b401b5e3172] [ 13.158581] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.161814] platform_probe+0xa2/0x150 [ 13.165029] really_probe+0x1e3/0x8a0 [ 13.168243] __driver_probe_device+0x18c/0x370 [ 13.171500] driver_probe_device+0x4a/0x120 [ 13.175000] __driver_attach+0x190/0x4a0 [ 13.178521] ? __pfx___driver_attach+0x10/0x10 [ 13.181771] bus_for_each_dev+0x106/0x180 [ 13.185033] ? __pfx__raw_spin_lock+0x10/0x10 [ 13.188229] ? __pfx_bus_for_each_dev+0x10/0x10 [ 13.191446] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.194382] bus_add_driver+0x29e/0x4d0 [ 13.197328] driver_register+0x1a5/0x360 [ 13.200283] ? __pfx_hid_gyro_3d_platform_driver_init+0x10/0x10 [hid_sensor_gyro_3d 63da36a143b775846ab2dbb86c343b401b5e3172] [ 13.203362] do_one_initcall+0xa7/0x380 [ 13.206432] ? __pfx_do_one_initcall+0x10/0x10 [ 13.210175] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.213211] ? kasan_unpoison+0x44/0x70 [ 13.216688] do_init_module+0x238/0x750 [ 13.219696] load_module+0x5011/0x6af0 [ 13.223096] ? kasan_save_stack+0x30/0x50 [ 13.226743] ? kasan_save_track+0x14/0x30 [ 13.230080] ? kasan_save_free_info+0x3b/0x60 [ 13.233323] ? poison_slab_object+0x109/0x180 [ 13.236778] ? __pfx_load_module+0x10/0x10 [ 13.239703] ? poison_slab_object+0x109/0x180 [ 13.243070] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.245924] ? init_module_from_file+0x13d/0x150 [ 13.248745] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.251503] ? init_module_from_file+0xdf/0x150 [ 13.254198] init_module_from_file+0xdf/0x150 [ 13.256826] ? __pfx_init_module_from_file+0x10/0x10 [ 13.259428] ? kasan_save_track+0x14/0x30 [ 13.261959] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.264471] ? kasan_save_free_info+0x3b/0x60 [ 13.267026] ? poison_slab_object+0x109/0x180 [ 13.269494] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.271949] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.274324] ? _raw_spin_lock+0x85/0xe0 [ 13.276671] ? __pfx__raw_spin_lock+0x10/0x10 [ 13.278963] ? __rseq_handle_notify_resume+0x1a6/0xad0 [ 13.281193] idempotent_init_module+0x23b/0x650 [ 13.283420] ? __pfx_idempotent_init_module+0x10/0x10 [ 13.285619] ? __pfx___seccomp_filter+0x10/0x10 [ 13.287714] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.289828] ? __fget_light+0x57/0x420 [ 13.291870] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.293880] ? security_capable+0x74/0xb0 [ 13.295820] __x64_sys_finit_module+0xbe/0x130 [ 13.297874] do_syscall_64+0x82/0x190 [ 13.299898] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.301905] ? irqtime_account_irq+0x3d/0x1f0 [ 13.303877] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.305753] ? __irq_exit_rcu+0x4e/0x130 [ 13.307577] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.309489] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 13.311371] RIP: 0033:0x7a21f96ade9d [ 13.313234] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 63 de 0c 00 f7 d8 64 89 01 48 [ 13.317051] RSP: 002b:00007ffeae934e78 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 13.319024] RAX: ffffffffffffffda RBX: 00005987276bfcf0 RCX: 00007a21f96ade9d [ 13.321100] RDX: 0000000000000004 RSI: 00007a21f8eda376 RDI: 000000000000001c [ 13.323314] RBP: 00007a21f8eda376 R08: 0000000000000001 R09: 00007ffeae934ec0 [ 13.325505] R10: 0000000000000050 R11: 0000000000000246 R12: 0000000000020000 [ 13.327637] R13: 00005987276c1250 R14: 0000000000000000 R15: 00005987276c4530 [ 13.329737] </TASK>
[ 13.333945] Allocated by task 139: [ 13.336111] kasan_save_stack+0x30/0x50 [ 13.336121] kasan_save_track+0x14/0x30 [ 13.336125] __kasan_kmalloc+0xaa/0xb0 [ 13.336129] amdtp_hid_probe+0xb1/0x440 [amd_sfh] [ 13.336138] amd_sfh_hid_client_init+0xb8a/0x10f0 [amd_sfh] [ 13.336144] sfh_init_work+0x47/0x120 [amd_sfh] [ 13.336150] process_one_work+0x673/0xeb0 [ 13.336155] worker_thread+0x795/0x1250 [ 13.336160] kthread+0x290/0x350 [ 13.336164] ret_from_fork+0x34/0x70 [ 13.336169] ret_from_fork_asm+0x1a/0x30
[ 13.338175] Freed by task 139: [ 13.340064] kasan_save_stack+0x30/0x50 [ 13.340072] kasan_save_track+0x14/0x30 [ 13.340076] kasan_save_free_info+0x3b/0x60 [ 13.340081] poison_slab_object+0x109/0x180 [ 13.340085] __kasan_slab_free+0x32/0x50 [ 13.340089] kfree+0xe5/0x310 [ 13.340094] amdtp_hid_remove+0xb2/0x160 [amd_sfh] [ 13.340102] amd_sfh_hid_client_deinit+0x324/0x640 [amd_sfh] [ 13.340107] amd_sfh_hid_client_init+0x94a/0x10f0 [amd_sfh] [ 13.340113] sfh_init_work+0x47/0x120 [amd_sfh] [ 13.340118] process_one_work+0x673/0xeb0 [ 13.340123] worker_thread+0x795/0x1250 [ 13.340127] kthread+0x290/0x350 [ 13.340132] ret_from_fork+0x34/0x70 [ 13.340136] ret_from_fork_asm+0x1a/0x30
[ 13.342482] The buggy address belongs to the object at ffff88813152f400
which belongs to the cache kmalloc-64 of size 64
[ 13.347357] The buggy address is located 8 bytes inside of
freed 64-byte region [ffff88813152f400, ffff88813152f440)[ 13.347367] The buggy address belongs to the physical page: [ 13.355409] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x13152f [ 13.355416] anon flags: 0x2ffff8000000000(node=0|zone=2|lastcpupid=0x1ffff) [ 13.355423] page_type: 0xffffefff(slab) [ 13.355429] raw: 02ffff8000000000 ffff8881000428c0 ffffea0004c43a00 0000000000000005 [ 13.355435] raw: 0000000000000000 0000000000200020 00000001ffffefff 0000000000000000 [ 13.355439] page dumped because: kasan: bad access detected
[ 13.357295] Memory state around the buggy address: [ 13.357299] ffff88813152f300: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 13.357303] ffff88813152f380: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 13.357306] >ffff88813152f400: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc [ 13.357309] ^ [ 13.357311] ffff88813152f480: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc [ 13.357315] ffff88813152f500: 00 00 00 00 00 00 00 06 fc fc fc fc fc fc fc fc [ 13.357318] ================================================================== [ 13.357405] Disabling lock debugging due to kernel taint [ 13.383534] Oops: general protection fault, probably for non-canonical address 0xe0a1bc4140000013: 0000 [#1] PREEMPT SMP KASAN NOPTI [ 13.383544] KASAN: maybe wild-memory-access in range [0x050e020a00000098-0x050e020a0000009f] [ 13.383551] CPU: 3 PID: 479 Comm: (udev-worker) Tainted: G B 6.10.0-arch1-2 #1 893bb55d7f0073f25c46adbb49eb3785fefd74b0 [ 13.383561] Hardware name: LENOVO 21CQCTO1WW/21CQCTO1WW, BIOS R22ET70W (1.40 ) 03/21/2024 [ 13.383565] RIP: 0010:amd_sfh_get_report+0x81/0x530 [amd_sfh] [ 13.383580] Code: 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 78 03 00 00 48 b8 00 00 00 00 00 fc ff df 4c 8b 63 08 49 8d 7c 24 10 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 08 3c 03 0f 8e 1a 03 00 00 45 8b 74 24 10 45 [ 13.383585] RSP: 0018:ffff8881261f7388 EFLAGS: 00010212 [ 13.383592] RAX: dffffc0000000000 RBX: ffff88813152f400 RCX: 0000000000000002 [ 13.383597] RDX: 00a1c04140000013 RSI: 0000000000000008 RDI: 050e020a0000009b [ 13.383600] RBP: ffff88814d010000 R08: 0000000000000002 R09: fffffbfff3ddb8c0 [ 13.383604] R10: ffffffff9eedc607 R11: ffff88810ce98000 R12: 050e020a0000008b [ 13.383607] R13: ffff88814d010000 R14: dffffc0000000000 R15: 0000000000000004 [ 13.383611] FS: 00007a21f94d0880(0000) GS:ffff8887e7d80000(0000) knlGS:0000000000000000 [ 13.383615] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 13.383618] CR2: 00007e0014c438f0 CR3: 000000012614c000 CR4: 0000000000f50ef0 [ 13.383622] PKRU: 55555554 [ 13.383625] Call Trace: [ 13.383629] <TASK> [ 13.383632] ? __die_body.cold+0x19/0x27 [ 13.383644] ? die_addr+0x46/0x70 [ 13.383652] ? exc_general_protection+0x150/0x240 [ 13.383664] ? asm_exc_general_protection+0x26/0x30 [ 13.383674] ? amd_sfh_get_report+0x81/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.383686] ? amd_sfh_get_report+0x3ec/0x530 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.383697] amdtp_hid_request+0xb8/0x110 [amd_sfh 05f43221435b5205f734cd9da29399130f398a38] [ 13.383706] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383713] sensor_hub_get_feature+0x1d3/0x540 [hid_sensor_hub 3f13be3016ff415bea03008d45d99da837ee3082] [ 13.383727] hid_sensor_parse_common_attributes+0x4d0/0xad0 [hid_sensor_iio_common c3a5cbe93969c28b122609768bbe23efe52eb8f5] [ 13.383739] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383745] ? __pfx_hid_sensor_parse_common_attributes+0x10/0x10 [hid_sensor_iio_common c3a5cbe93969c28b122609768bbe23efe52eb8f5] [ 13.383753] ? _raw_spin_lock_irqsave+0x96/0xf0 [ 13.383762] ? __pfx__raw_spin_lock_irqsave+0x10/0x10 [ 13.383768] ? devm_iio_device_alloc+0x34/0x50 [industrialio 3d261d5e5765625d2b052be40e526d62b1d2123b] [ 13.383790] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383795] ? __devm_add_action+0x167/0x1d0 [ 13.383806] hid_gyro_3d_probe+0x120/0x7f0 [hid_sensor_gyro_3d 63da36a143b775846ab2dbb86c343b401b5e3172] [ 13.383818] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383826] platform_probe+0xa2/0x150 [ 13.383832] really_probe+0x1e3/0x8a0 [ 13.383838] __driver_probe_device+0x18c/0x370 [ 13.383844] driver_probe_device+0x4a/0x120 [ 13.383851] __driver_attach+0x190/0x4a0 [ 13.383857] ? __pfx___driver_attach+0x10/0x10 [ 13.383863] bus_for_each_dev+0x106/0x180 [ 13.383868] ? __pfx__raw_spin_lock+0x10/0x10 [ 13.383874] ? __pfx_bus_for_each_dev+0x10/0x10 [ 13.383880] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383887] bus_add_driver+0x29e/0x4d0 [ 13.383895] driver_register+0x1a5/0x360 [ 13.383902] ? __pfx_hid_gyro_3d_platform_driver_init+0x10/0x10 [hid_sensor_gyro_3d 63da36a143b775846ab2dbb86c343b401b5e3172] [ 13.383910] do_one_initcall+0xa7/0x380 [ 13.383919] ? __pfx_do_one_initcall+0x10/0x10 [ 13.383927] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.383933] ? kasan_unpoison+0x44/0x70 [ 13.383943] do_init_module+0x238/0x750 [ 13.383955] load_module+0x5011/0x6af0 [ 13.383962] ? kasan_save_stack+0x30/0x50 [ 13.383968] ? kasan_save_track+0x14/0x30 [ 13.383973] ? kasan_save_free_info+0x3b/0x60 [ 13.383980] ? poison_slab_object+0x109/0x180 [ 13.383993] ? __pfx_load_module+0x10/0x10 [ 13.384007] ? poison_slab_object+0x109/0x180 [ 13.384012] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384018] ? init_module_from_file+0x13d/0x150 [ 13.384025] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384032] ? init_module_from_file+0xdf/0x150 [ 13.384037] init_module_from_file+0xdf/0x150 [ 13.384044] ? __pfx_init_module_from_file+0x10/0x10 [ 13.384050] ? kasan_save_track+0x14/0x30 [ 13.384055] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384060] ? kasan_save_free_info+0x3b/0x60 [ 13.384066] ? poison_slab_object+0x109/0x180 [ 13.384071] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384080] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384085] ? _raw_spin_lock+0x85/0xe0 [ 13.384091] ? __pfx__raw_spin_lock+0x10/0x10 [ 13.384096] ? __rseq_handle_notify_resume+0x1a6/0xad0 [ 13.384106] idempotent_init_module+0x23b/0x650 [ 13.384114] ? __pfx_idempotent_init_module+0x10/0x10 [ 13.384120] ? __pfx___seccomp_filter+0x10/0x10 [ 13.384129] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384135] ? __fget_light+0x57/0x420 [ 13.384142] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384147] ? security_capable+0x74/0xb0 [ 13.384157] __x64_sys_finit_module+0xbe/0x130 [ 13.384164] do_syscall_64+0x82/0x190 [ 13.384174] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384179] ? irqtime_account_irq+0x3d/0x1f0 [ 13.384188] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384193] ? __irq_exit_rcu+0x4e/0x130 [ 13.384201] ? srso_alias_return_thunk+0x5/0xfbef5 [ 13.384206] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 13.384212] RIP: 0033:0x7a21f96ade9d [ 13.384263] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 63 de 0c 00 f7 d8 64 89 01 48 [ 13.384267] RSP: 002b:00007ffeae934e78 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 13.384273] RAX: ffffffffffffffda RBX: 00005987276bfcf0 RCX: 00007a21f96ade9d [ 13.384277] RDX: 0000000000000004 RSI: 00007a21f8eda376 RDI: 000000000000001c [ 13.384280] RBP: 00007a21f8eda376 R08: 0000000000000001 R09: 00007ffeae934ec0 [ 13.384284] R10: 0000000000000050 R11: 0000000000000246 R12: 0000000000020000 [ 13.384288] R13: 00005987276c1250 R14: 0000000000000000 R15: 00005987276c4530 [ 13.384297] </TASK> [ 13.384299] Modules linked in: soundwire_amd(+) hid_sensor_gyro_3d(+) hid_sensor_magn_3d hid_sensor_accel_3d soundwire_generic_allocation amdxcp hid_sensor_trigger drm_exec industrialio_triggered_buffer soundwire_bus gpu_sched kvm_amd kfifo_buf qmi_helpers joydev drm_buddy hid_sensor_iio_common mousedev snd_soc_core industrialio i2c_algo_bit mac80211 snd_compress drm_suballoc_helper kvm snd_hda_intel drm_ttm_helper ac97_bus snd_pcm_dmaengine snd_intel_dspcfg ttm thinkpad_acpi(+) snd_intel_sdw_acpi hid_sensor_hub snd_rpl_pci_acp6x drm_display_helper snd_hda_codec hid_multitouch libarc4 snd_acp_pci platform_profile think_lmi(+) hid_generic firmware_attributes_class wmi_bmof cec snd_acp_legacy_common sparse_keymap rapl snd_hda_core psmouse cfg80211 pcspkr snd_pci_acp6x snd_hwdep video snd_pcm snd_pci_acp5x snd_timer snd_rn_pci_acp3x ucsi_acpi snd_acp_config snd sp5100_tco rfkill snd_soc_acpi typec_ucsi thunderbolt amd_sfh k10temp mhi soundcore i2c_piix4 snd_pci_acp3x typec i2c_hid_acpi roles i2c_hid wmi acpi_tad amd_pmc [ 13.384454] mac_hid i2c_dev crypto_user loop nfnetlink zram ip_tables x_tables dm_crypt cbc encrypted_keys trusted asn1_encoder tee dm_mod crct10dif_pclmul crc32_pclmul polyval_clmulni polyval_generic gf128mul ghash_clmulni_intel serio_raw sha512_ssse3 atkbd sha256_ssse3 libps2 sha1_ssse3 vivaldi_fmap nvme aesni_intel crypto_simd nvme_core cryptd ccp xhci_pci i8042 nvme_auth xhci_pci_renesas serio vfat fat btrfs blake2b_generic libcrc32c crc32c_generic crc32c_intel xor raid6_pq [ 13.384552] ---[ end trace 0000000000000000 ]---
KASAN reports a use-after-free of hid->driver_data in function amd_sfh_get_report(). The backtrace indicates that the function is called by amdtp_hid_request() which is one of the callbacks of hid device. The current make sure that driver_data is freed only once hid_destroy_device() returned.
Note that I observed the crash both on v6.9.9 and v6.10.0. The code seems to be as it was from the early days of the driver.
--- drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hid/amd-sfh-hid/amd_sfh_hid.c +3 -1
@@ -171,11 +171,13 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)void amdtp_hid_remove (struct amdtp_cl_data *cli_data) {int i; +struct amdtp_hid_data *hid_data;for (i =0 ; i < cli_data->num_hid_devices; ++i) {if (cli_data->hid_sensor_hubs[i]) { -kfree (cli_data->hid_sensor_hubs[i]->driver_data); + hid_data = cli_data->hid_sensor_hubs[i]->driver_data;hid_destroy_device (cli_data->hid_sensor_hubs[i]); +kfree (hid_data); cli_data->hid_sensor_hubs[i] =NULL ; } }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 267/375 Input: uinput - reject requests with unreasonable number of slots
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
[ Upstream commit 206f533a0a7c683982af473079c4111f4a0f9f5e ]
From: Dmitry Torokhov <[email protected]>
When exercising uinput interface syzkaller may try setting up device with a really large number of slots, which causes memory allocation failure in input_mt_init_slots(). While this allocation failure is handled properly and request is rejected, it results in syzkaller reports. Additionally, such request may put undue burden on the system which will try to free a lot of memory for a bogus request.
Fix it by limiting allowed number of slots to 100. This can easily be extended if we see devices that can track more than 100 contacts.
--- drivers/input/misc/uinput.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/input/misc/uinput.c +14 -0
@@ -417,6 +417,20 @@ static int uinput_validate_absinfo(struct input_dev *dev, unsigned int code,return -EINVAL ; } +/* +* Limit number of contacts to a reasonable value (100). This +* ensures that we need less than 2 pages for struct input_mt +* (we are not using in-kernel slot assignment so not going to +* allocate memory for the "red" table), and we should have no +* trouble getting this much memory. +*/ +if (code ==ABS_MT_SLOT && max >99 ) { +printk (KERN_DEBUG +"%s: unreasonably large number of slots requested: %d\n" , +UINPUT_NAME , max); +return -EINVAL ; + } +return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 268/375 usbnet: ipheth: race between ipheth_close and error handling
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
[ Upstream commit e5876b088ba03a62124266fa20d00e65533c7269 ]
ipheth_sndbulk_callback() can submit carrier_work as a part of its error handling. That means that the driver must make sure that the work is cancelled after it has made sure that no more URB can terminate with an error condition.
Hence the order of actions in ipheth_close() needs to be inverted.
--- drivers/net/usb/ipheth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/ipheth.c +1 -1
@@ -475,8 +475,8 @@ static int ipheth_close(struct net_device *net) {struct ipheth_device *dev =netdev_priv (net); -cancel_delayed_work_sync (&dev->carrier_work);netif_stop_queue (net); +cancel_delayed_work_sync (&dev->carrier_work);return 0 ; }
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 269/375 Squashfs: sanity check symbolic link size
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phillip Lougher <[email protected]>
[ Upstream commit 810ee43d9cd245d138a2733d87a24858a23f577d ]
Syzkiller reports a "KMSAN: uninit-value in pick_link" bug.
This is caused by an uninitialised page, which is ultimately caused by a corrupted symbolic link size read from disk.
The reason why the corrupted symlink size causes an uninitialised page is due to the following sequence of events:
1. squashfs_read_inode() is called to read the symbolic link from disk. This assigns the corrupted value 3875536935 to inode->i_size.
2. Later squashfs_symlink_read_folio() is called, which assigns this corrupted value to the length variable, which being a signed int, overflows producing a negative number.
3. The following loop that fills in the page contents checks that the copied bytes is less than length, which being negative means the loop is skipped, producing an uninitialised page.
This patch adds a sanity check which checks that the symbolic link size is not larger than expected.
--
V2: fix spelling mistake.
--- fs/squashfs/inode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/squashfs/inode.c +6 -1
@@ -279,8 +279,13 @@ int squashfs_read_inode(struct inode *inode, long long ino)if (err <0 ) goto failed_read; -set_nlink (inode,le32_to_cpu (sqsh_ino->nlink)); inode->i_size =le32_to_cpu (sqsh_ino->symlink_size); +if (inode->i_size >PAGE_SIZE ) { +ERROR ("Corrupted symlink\n" ); +return -EINVAL ; + } + +set_nlink (inode,le32_to_cpu (sqsh_ino->nlink)); inode->i_op = &squashfs_symlink_inode_ops;inode_nohighmem (inode); inode->i_data.a_ops = &squashfs_symlink_aops;
Signature · 1 line
2.43.0
Greg Kroah-Hartman
maintainerPATCH 270/375 of/irq: Prevent device address out-of-bounds read in interrupt map walk
In reply to Greg Kroah-Hartman6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
[ Upstream commit b739dffa5d570b411d4bdf4bb9b8dfd6b7d72305 ]
When of_irq_parse_raw() is invoked with a device address smaller than the interrupt parent node (from #address-cells property), KASAN detects the following out-of-bounds read when populating the initial match table (dyndbg="func of_irq_parse_* +p"):
OF: of_irq_parse_one: dev=/soc@0/picasso/watchdog, index=0
OF: parent=/soc@0/pci@878000000000/gpio0@17,0, intsize=2
OF: intspec=4
OF: of_irq_parse_raw: ipar=/soc@0/pci@878000000000/gpio0@17,0, size=2
OF: -> addrsize=3
==================================================================
BUG: KASAN: slab-out-of-bounds in of_irq_parse_raw+0x2b8/0x8d0
Read of size 4 at addr ffffff81beca5608 by task bash/764
CPU: 1 PID: 764 Comm: bash Tainted: G O 6.1.67-484c613561-nokia_sm_arm64 #1
Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2023.01-12.24.03-dirty 01/01/2023
Call trace:
dump_backtrace+0xdc/0x130
show_stack+0x1c/0x30
dump_stack_lvl+0x6c/0x84
print_report+0x150/0x448
kasan_report+0x98/0x140
__asan_load4+0x78/0xa0
of_irq_parse_raw+0x2b8/0x8d0
of_irq_parse_one+0x24c/0x270
parse_interrupts+0xc0/0x120
of_fwnode_add_links+0x100/0x2d0
fw_devlink_parse_fwtree+0x64/0xc0
device_add+0xb38/0xc30
of_device_add+0x64/0x90
of_platform_device_create_pdata+0xd0/0x170
of_platform_bus_create+0x244/0x600
of_platform_notify+0x1b0/0x254
blocking_notifier_call_chain+0x9c/0xd0
__of_changeset_entry_notify+0x1b8/0x230
__of_changeset_apply_notify+0x54/0xe4
of_overlay_fdt_apply+0xc04/0xd94
...
The buggy address belongs to the object at ffffff81beca5600
which belongs to the cache kmalloc-128 of size 128
The buggy address is located 8 bytes inside of
128-byte region [ffffff81beca5600, ffffff81beca5680)
The buggy address belongs to the physical page:
page:00000000230d3d03 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1beca4
head:00000000230d3d03 order:1 compound_mapcount:0 compound_pincount:0
flags: 0x8000000000010200(slab|head|zone=2)
raw: 8000000000010200 0000000000000000 dead000000000122 ffffff810000c300
raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffffff81beca5500: 04 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffffff81beca5580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffffff81beca5600: 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffffff81beca5680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffffff81beca5700: 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc
==================================================================
OF: -> got it !Prevent the out-of-bounds read by copying the device address into a buffer of sufficient size.
--- drivers/of/irq.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/of/irq.c +11 -4
@@ -344,7 +344,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_arstruct device_node *p;const __be32 *addr;u32 intsize; -int i, res; +int i, res, addr_len; +__be32 addr_buf[3 ] = {0 };pr_debug ("of_irq_parse_one: dev=%pOF, index=%d\n" , device, index);
@@ -353,13 +354,19 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_arreturn of_irq_parse_oldworld (device, index, out_irq);/* Get the reg property (if any) */ - addr =of_get_property (device,"reg" ,NULL ); + addr =of_get_property (device,"reg" , &addr_len); + +/* Prevent out-of-bounds read in case of longer interrupt parent address size */ +if (addr_len > (3 *sizeof (__be32))) + addr_len =3 *sizeof (__be32); +if (addr) +memcpy (addr_buf, addr, addr_len);/* Try the new-style interrupts-extended first */ res =of_parse_phandle_with_args (device,"interrupts-extended" ,"#interrupt-cells" , index, out_irq);if (!res) -return of_irq_parse_raw (addr, out_irq); +return of_irq_parse_raw (addr_buf, out_irq);/* Look for the interrupt parent. */ p =of_irq_find_parent (device);
@@ -389,7 +396,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar/* Check if there are any interrupt-map translations to process */ - res =of_irq_parse_raw (addr, out_irq); + res =of_irq_parse_raw (addr_buf, out_irq); out:of_node_put (p);return res;
Signature · 1 line
2.43.0