From: Greg Kroah-Hartman Date: Tue, 18 Apr 2023 10:16:55 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.14.313~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6db938c9b87f9fab537e686a0ddd73d861fc6068;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: cgroup-cpuset-add-cpuset_can_fork-and-cpuset_cancel_fork-methods.patch cgroup-cpuset-change-references-of-cpuset_mutex-to-cpuset_rwsem.patch cgroup-cpuset-make-cpuset_fork-handle-clone_into_cgroup-properly.patch cgroup-cpuset-skip-spread-flags-update-on-v2.patch coresight-etm4-fix-for-loop-drvdata-nr_addr_cmp-range-bug.patch kbuild-check-config_as_is_llvm-instead-of-llvm_ias.patch kbuild-check-the-minimum-assembler-version-in-kconfig.patch kbuild-switch-to-f-variants-of-integrated-assembler-flag.patch riscv-handle-zicsr-zifencei-issues-between-clang-and-binutils.patch watchdog-sbsa_wdog-make-sure-the-timeout-programming-is-within-the-limits.patch --- diff --git a/queue-5.10/cgroup-cpuset-add-cpuset_can_fork-and-cpuset_cancel_fork-methods.patch b/queue-5.10/cgroup-cpuset-add-cpuset_can_fork-and-cpuset_cancel_fork-methods.patch new file mode 100644 index 00000000000..3606fa7284c --- /dev/null +++ b/queue-5.10/cgroup-cpuset-add-cpuset_can_fork-and-cpuset_cancel_fork-methods.patch @@ -0,0 +1,162 @@ +From stable-owner@vger.kernel.org Mon Apr 17 19:21:21 2023 +From: Waiman Long +Date: Mon, 17 Apr 2023 13:19:58 -0400 +Subject: cgroup/cpuset: Add cpuset_can_fork() and cpuset_cancel_fork() methods +To: Greg Kroah-Hartman , stable@vger.kernel.org +Cc: "Tejun Heo" , "Michal Koutný" , "Giuseppe Scrivano" , "Waiman Long" +Message-ID: <20230417171958.3389333-4-longman@redhat.com> + +From: Waiman Long + +commit eee87853794187f6adbe19533ed79c8b44b36a91 upstream. + +In the case of CLONE_INTO_CGROUP, not all cpusets are ready to accept +new tasks. It is too late to check that in cpuset_fork(). So we need +to add the cpuset_can_fork() and cpuset_cancel_fork() methods to +pre-check it before we can allow attachment to a different cpuset. + +We also need to set the attach_in_progress flag to alert other code +that a new task is going to be added to the cpuset. + +Fixes: ef2c41cf38a7 ("clone3: allow spawning processes into cgroups") +Suggested-by: Michal Koutný +Signed-off-by: Waiman Long +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/cgroup/cpuset.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 83 insertions(+), 5 deletions(-) + +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2151,6 +2151,18 @@ static int fmeter_getrate(struct fmeter + + static struct cpuset *cpuset_attach_old_cs; + ++/* ++ * Check to see if a cpuset can accept a new task ++ * For v1, cpus_allowed and mems_allowed can't be empty. ++ */ ++static int cpuset_can_attach_check(struct cpuset *cs) ++{ ++ if (!is_in_v2_mode() && ++ (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) ++ return -ENOSPC; ++ return 0; ++} ++ + /* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */ + static int cpuset_can_attach(struct cgroup_taskset *tset) + { +@@ -2165,10 +2177,8 @@ static int cpuset_can_attach(struct cgro + + percpu_down_write(&cpuset_rwsem); + +- /* allow moving tasks into an empty cpuset if on default hierarchy */ +- ret = -ENOSPC; +- if (!is_in_v2_mode() && +- (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))) ++ ret = cpuset_can_attach_check(cs); ++ if (ret) + goto out_unlock; + + cgroup_taskset_for_each(task, css, tset) { +@@ -2185,7 +2195,6 @@ static int cpuset_can_attach(struct cgro + * changes which zero cpus/mems_allowed. + */ + cs->attach_in_progress++; +- ret = 0; + out_unlock: + percpu_up_write(&cpuset_rwsem); + return ret; +@@ -2913,6 +2922,68 @@ static void cpuset_bind(struct cgroup_su + } + + /* ++ * In case the child is cloned into a cpuset different from its parent, ++ * additional checks are done to see if the move is allowed. ++ */ ++static int cpuset_can_fork(struct task_struct *task, struct css_set *cset) ++{ ++ struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]); ++ bool same_cs; ++ int ret; ++ ++ rcu_read_lock(); ++ same_cs = (cs == task_cs(current)); ++ rcu_read_unlock(); ++ ++ if (same_cs) ++ return 0; ++ ++ lockdep_assert_held(&cgroup_mutex); ++ percpu_down_write(&cpuset_rwsem); ++ ++ /* Check to see if task is allowed in the cpuset */ ++ ret = cpuset_can_attach_check(cs); ++ if (ret) ++ goto out_unlock; ++ ++ ret = task_can_attach(task, cs->effective_cpus); ++ if (ret) ++ goto out_unlock; ++ ++ ret = security_task_setscheduler(task); ++ if (ret) ++ goto out_unlock; ++ ++ /* ++ * Mark attach is in progress. This makes validate_change() fail ++ * changes which zero cpus/mems_allowed. ++ */ ++ cs->attach_in_progress++; ++out_unlock: ++ percpu_up_write(&cpuset_rwsem); ++ return ret; ++} ++ ++static void cpuset_cancel_fork(struct task_struct *task, struct css_set *cset) ++{ ++ struct cpuset *cs = css_cs(cset->subsys[cpuset_cgrp_id]); ++ bool same_cs; ++ ++ rcu_read_lock(); ++ same_cs = (cs == task_cs(current)); ++ rcu_read_unlock(); ++ ++ if (same_cs) ++ return; ++ ++ percpu_down_write(&cpuset_rwsem); ++ cs->attach_in_progress--; ++ if (!cs->attach_in_progress) ++ wake_up(&cpuset_attach_wq); ++ percpu_up_write(&cpuset_rwsem); ++} ++ ++/* + * Make sure the new task conform to the current state of its parent, + * which could have been changed by cpuset just after it inherits the + * state from the parent and before it sits on the cgroup's task list. +@@ -2946,6 +3017,11 @@ static void cpuset_fork(struct task_stru + else + guarantee_online_cpus(cs, cpus_attach); + cpuset_attach_task(cs, task); ++ ++ cs->attach_in_progress--; ++ if (!cs->attach_in_progress) ++ wake_up(&cpuset_attach_wq); ++ + percpu_up_write(&cpuset_rwsem); + } + +@@ -2959,6 +3035,8 @@ struct cgroup_subsys cpuset_cgrp_subsys + .attach = cpuset_attach, + .post_attach = cpuset_post_attach, + .bind = cpuset_bind, ++ .can_fork = cpuset_can_fork, ++ .cancel_fork = cpuset_cancel_fork, + .fork = cpuset_fork, + .legacy_cftypes = legacy_files, + .dfl_cftypes = dfl_files, diff --git a/queue-5.10/cgroup-cpuset-change-references-of-cpuset_mutex-to-cpuset_rwsem.patch b/queue-5.10/cgroup-cpuset-change-references-of-cpuset_mutex-to-cpuset_rwsem.patch new file mode 100644 index 00000000000..6b30305db7a --- /dev/null +++ b/queue-5.10/cgroup-cpuset-change-references-of-cpuset_mutex-to-cpuset_rwsem.patch @@ -0,0 +1,257 @@ +From stable-owner@vger.kernel.org Mon Apr 17 19:21:31 2023 +From: Waiman Long +Date: Mon, 17 Apr 2023 13:19:55 -0400 +Subject: cgroup/cpuset: Change references of cpuset_mutex to cpuset_rwsem +To: Greg Kroah-Hartman , stable@vger.kernel.org +Cc: "Tejun Heo" , "Michal Koutný" , "Giuseppe Scrivano" , "Waiman Long" +Message-ID: <20230417171958.3389333-1-longman@redhat.com> + +From: Waiman Long + +Commit b94f9ac79a7395c2d6171cc753cc27942df0be73 upstream. + +Since commit 1243dc518c9d ("cgroup/cpuset: Convert cpuset_mutex to +percpu_rwsem"), cpuset_mutex has been replaced by cpuset_rwsem which is +a percpu rwsem. However, the comments in kernel/cgroup/cpuset.c still +reference cpuset_mutex which are now incorrect. + +Change all the references of cpuset_mutex to cpuset_rwsem. + +Fixes: 1243dc518c9d ("cgroup/cpuset: Convert cpuset_mutex to percpu_rwsem") +Signed-off-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/cgroup/cpuset.c | 56 +++++++++++++++++++++++++------------------------ + 1 file changed, 29 insertions(+), 27 deletions(-) + +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -299,17 +299,19 @@ static struct cpuset top_cpuset = { + if (is_cpuset_online(((des_cs) = css_cs((pos_css))))) + + /* +- * There are two global locks guarding cpuset structures - cpuset_mutex and ++ * There are two global locks guarding cpuset structures - cpuset_rwsem and + * callback_lock. We also require taking task_lock() when dereferencing a + * task's cpuset pointer. See "The task_lock() exception", at the end of this +- * comment. ++ * comment. The cpuset code uses only cpuset_rwsem write lock. Other ++ * kernel subsystems can use cpuset_read_lock()/cpuset_read_unlock() to ++ * prevent change to cpuset structures. + * + * A task must hold both locks to modify cpusets. If a task holds +- * cpuset_mutex, then it blocks others wanting that mutex, ensuring that it ++ * cpuset_rwsem, it blocks others wanting that rwsem, ensuring that it + * is the only task able to also acquire callback_lock and be able to + * modify cpusets. It can perform various checks on the cpuset structure + * first, knowing nothing will change. It can also allocate memory while +- * just holding cpuset_mutex. While it is performing these checks, various ++ * just holding cpuset_rwsem. While it is performing these checks, various + * callback routines can briefly acquire callback_lock to query cpusets. + * Once it is ready to make the changes, it takes callback_lock, blocking + * everyone else. +@@ -380,7 +382,7 @@ static inline bool is_in_v2_mode(void) + * One way or another, we guarantee to return some non-empty subset + * of cpu_online_mask. + * +- * Call with callback_lock or cpuset_mutex held. ++ * Call with callback_lock or cpuset_rwsem held. + */ + static void guarantee_online_cpus(struct cpuset *cs, struct cpumask *pmask) + { +@@ -410,7 +412,7 @@ static void guarantee_online_cpus(struct + * One way or another, we guarantee to return some non-empty subset + * of node_states[N_MEMORY]. + * +- * Call with callback_lock or cpuset_mutex held. ++ * Call with callback_lock or cpuset_rwsem held. + */ + static void guarantee_online_mems(struct cpuset *cs, nodemask_t *pmask) + { +@@ -422,7 +424,7 @@ static void guarantee_online_mems(struct + /* + * update task's spread flag if cpuset's page/slab spread flag is set + * +- * Call with callback_lock or cpuset_mutex held. ++ * Call with callback_lock or cpuset_rwsem held. + */ + static void cpuset_update_task_spread_flag(struct cpuset *cs, + struct task_struct *tsk) +@@ -443,7 +445,7 @@ static void cpuset_update_task_spread_fl + * + * One cpuset is a subset of another if all its allowed CPUs and + * Memory Nodes are a subset of the other, and its exclusive flags +- * are only set if the other's are set. Call holding cpuset_mutex. ++ * are only set if the other's are set. Call holding cpuset_rwsem. + */ + + static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q) +@@ -552,7 +554,7 @@ static inline void free_cpuset(struct cp + * If we replaced the flag and mask values of the current cpuset + * (cur) with those values in the trial cpuset (trial), would + * our various subset and exclusive rules still be valid? Presumes +- * cpuset_mutex held. ++ * cpuset_rwsem held. + * + * 'cur' is the address of an actual, in-use cpuset. Operations + * such as list traversal that depend on the actual address of the +@@ -675,7 +677,7 @@ static void update_domain_attr_tree(stru + rcu_read_unlock(); + } + +-/* Must be called with cpuset_mutex held. */ ++/* Must be called with cpuset_rwsem held. */ + static inline int nr_cpusets(void) + { + /* jump label reference count + the top-level cpuset */ +@@ -701,7 +703,7 @@ static inline int nr_cpusets(void) + * domains when operating in the severe memory shortage situations + * that could cause allocation failures below. + * +- * Must be called with cpuset_mutex held. ++ * Must be called with cpuset_rwsem held. + * + * The three key local variables below are: + * cp - cpuset pointer, used (together with pos_css) to perform a +@@ -980,7 +982,7 @@ partition_and_rebuild_sched_domains(int + * 'cpus' is removed, then call this routine to rebuild the + * scheduler's dynamic sched domains. + * +- * Call with cpuset_mutex held. Takes get_online_cpus(). ++ * Call with cpuset_rwsem held. Takes get_online_cpus(). + */ + static void rebuild_sched_domains_locked(void) + { +@@ -1053,7 +1055,7 @@ void rebuild_sched_domains(void) + * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed + * + * Iterate through each task of @cs updating its cpus_allowed to the +- * effective cpuset's. As this function is called with cpuset_mutex held, ++ * effective cpuset's. As this function is called with cpuset_rwsem held, + * cpuset membership stays stable. + */ + static void update_tasks_cpumask(struct cpuset *cs) +@@ -1328,7 +1330,7 @@ static int update_parent_subparts_cpumas + * + * On legacy hierachy, effective_cpus will be the same with cpu_allowed. + * +- * Called with cpuset_mutex held ++ * Called with cpuset_rwsem held + */ + static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp) + { +@@ -1688,12 +1690,12 @@ static void *cpuset_being_rebound; + * @cs: the cpuset in which each task's mems_allowed mask needs to be changed + * + * Iterate through each task of @cs updating its mems_allowed to the +- * effective cpuset's. As this function is called with cpuset_mutex held, ++ * effective cpuset's. As this function is called with cpuset_rwsem held, + * cpuset membership stays stable. + */ + static void update_tasks_nodemask(struct cpuset *cs) + { +- static nodemask_t newmems; /* protected by cpuset_mutex */ ++ static nodemask_t newmems; /* protected by cpuset_rwsem */ + struct css_task_iter it; + struct task_struct *task; + +@@ -1706,7 +1708,7 @@ static void update_tasks_nodemask(struct + * take while holding tasklist_lock. Forks can happen - the + * mpol_dup() cpuset_being_rebound check will catch such forks, + * and rebind their vma mempolicies too. Because we still hold +- * the global cpuset_mutex, we know that no other rebind effort ++ * the global cpuset_rwsem, we know that no other rebind effort + * will be contending for the global variable cpuset_being_rebound. + * It's ok if we rebind the same mm twice; mpol_rebind_mm() + * is idempotent. Also migrate pages in each mm to new nodes. +@@ -1752,7 +1754,7 @@ static void update_tasks_nodemask(struct + * + * On legacy hiearchy, effective_mems will be the same with mems_allowed. + * +- * Called with cpuset_mutex held ++ * Called with cpuset_rwsem held + */ + static void update_nodemasks_hier(struct cpuset *cs, nodemask_t *new_mems) + { +@@ -1805,7 +1807,7 @@ static void update_nodemasks_hier(struct + * mempolicies and if the cpuset is marked 'memory_migrate', + * migrate the tasks pages to the new memory. + * +- * Call with cpuset_mutex held. May take callback_lock during call. ++ * Call with cpuset_rwsem held. May take callback_lock during call. + * Will take tasklist_lock, scan tasklist for tasks in cpuset cs, + * lock each such tasks mm->mmap_lock, scan its vma's and rebind + * their mempolicies to the cpusets new mems_allowed. +@@ -1895,7 +1897,7 @@ static int update_relax_domain_level(str + * @cs: the cpuset in which each task's spread flags needs to be changed + * + * Iterate through each task of @cs updating its spread flags. As this +- * function is called with cpuset_mutex held, cpuset membership stays ++ * function is called with cpuset_rwsem held, cpuset membership stays + * stable. + */ + static void update_tasks_flags(struct cpuset *cs) +@@ -1915,7 +1917,7 @@ static void update_tasks_flags(struct cp + * cs: the cpuset to update + * turning_on: whether the flag is being set or cleared + * +- * Call with cpuset_mutex held. ++ * Call with cpuset_rwsem held. + */ + + static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, +@@ -1964,7 +1966,7 @@ out: + * cs: the cpuset to update + * new_prs: new partition root state + * +- * Call with cpuset_mutex held. ++ * Call with cpuset_rwsem held. + */ + static int update_prstate(struct cpuset *cs, int new_prs) + { +@@ -2145,7 +2147,7 @@ static int fmeter_getrate(struct fmeter + + static struct cpuset *cpuset_attach_old_cs; + +-/* Called by cgroups to determine if a cpuset is usable; cpuset_mutex held */ ++/* Called by cgroups to determine if a cpuset is usable; cpuset_rwsem held */ + static int cpuset_can_attach(struct cgroup_taskset *tset) + { + struct cgroup_subsys_state *css; +@@ -2201,7 +2203,7 @@ static void cpuset_cancel_attach(struct + } + + /* +- * Protected by cpuset_mutex. cpus_attach is used only by cpuset_attach() ++ * Protected by cpuset_rwsem. cpus_attach is used only by cpuset_attach() + * but we can't allocate it dynamically there. Define it global and + * allocate from cpuset_init(). + */ +@@ -2209,7 +2211,7 @@ static cpumask_var_t cpus_attach; + + static void cpuset_attach(struct cgroup_taskset *tset) + { +- /* static buf protected by cpuset_mutex */ ++ /* static buf protected by cpuset_rwsem */ + static nodemask_t cpuset_attach_nodemask_to; + struct task_struct *task; + struct task_struct *leader; +@@ -2402,7 +2404,7 @@ static ssize_t cpuset_write_resmask(stru + * operation like this one can lead to a deadlock through kernfs + * active_ref protection. Let's break the protection. Losing the + * protection is okay as we check whether @cs is online after +- * grabbing cpuset_mutex anyway. This only happens on the legacy ++ * grabbing cpuset_rwsem anyway. This only happens on the legacy + * hierarchies. + */ + css_get(&cs->css); +@@ -3641,7 +3643,7 @@ void __cpuset_memory_pressure_bump(void) + * - Used for /proc//cpuset. + * - No need to task_lock(tsk) on this tsk->cpuset reference, as it + * doesn't really matter if tsk->cpuset changes after we read it, +- * and we take cpuset_mutex, keeping cpuset_attach() from changing it ++ * and we take cpuset_rwsem, keeping cpuset_attach() from changing it + * anyway. + */ + int proc_cpuset_show(struct seq_file *m, struct pid_namespace *ns, diff --git a/queue-5.10/cgroup-cpuset-make-cpuset_fork-handle-clone_into_cgroup-properly.patch b/queue-5.10/cgroup-cpuset-make-cpuset_fork-handle-clone_into_cgroup-properly.patch new file mode 100644 index 00000000000..7b7e664dfea --- /dev/null +++ b/queue-5.10/cgroup-cpuset-make-cpuset_fork-handle-clone_into_cgroup-properly.patch @@ -0,0 +1,129 @@ +From stable-owner@vger.kernel.org Mon Apr 17 19:21:27 2023 +From: Waiman Long +Date: Mon, 17 Apr 2023 13:19:57 -0400 +Subject: cgroup/cpuset: Make cpuset_fork() handle CLONE_INTO_CGROUP properly +To: Greg Kroah-Hartman , stable@vger.kernel.org +Cc: "Tejun Heo" , "Michal Koutný" , "Giuseppe Scrivano" , "Waiman Long" +Message-ID: <20230417171958.3389333-3-longman@redhat.com> + +From: Waiman Long + +commit 42a11bf5c5436e91b040aeb04063be1710bb9f9c upstream. + +By default, the clone(2) syscall spawn a child process into the same +cgroup as its parent. With the use of the CLONE_INTO_CGROUP flag +introduced by commit ef2c41cf38a7 ("clone3: allow spawning processes +into cgroups"), the child will be spawned into a different cgroup which +is somewhat similar to writing the child's tid into "cgroup.threads". + +The current cpuset_fork() method does not properly handle the +CLONE_INTO_CGROUP case where the cpuset of the child may be different +from that of its parent. Update the cpuset_fork() method to treat the +CLONE_INTO_CGROUP case similar to cpuset_attach(). + +Since the newly cloned task has not been running yet, its actual +memory usage isn't known. So it is not necessary to make change to mm +in cpuset_fork(). + +Fixes: ef2c41cf38a7 ("clone3: allow spawning processes into cgroups") +Reported-by: Giuseppe Scrivano +Signed-off-by: Waiman Long +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/cgroup/cpuset.c | 60 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 44 insertions(+), 16 deletions(-) + +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -2207,16 +2207,29 @@ static void cpuset_cancel_attach(struct + } + + /* +- * Protected by cpuset_rwsem. cpus_attach is used only by cpuset_attach() ++ * Protected by cpuset_rwsem. cpus_attach is used only by cpuset_attach_task() + * but we can't allocate it dynamically there. Define it global and + * allocate from cpuset_init(). + */ + static cpumask_var_t cpus_attach; ++static nodemask_t cpuset_attach_nodemask_to; ++ ++static void cpuset_attach_task(struct cpuset *cs, struct task_struct *task) ++{ ++ percpu_rwsem_assert_held(&cpuset_rwsem); ++ ++ /* ++ * can_attach beforehand should guarantee that this doesn't ++ * fail. TODO: have a better way to handle failure here ++ */ ++ WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach)); ++ ++ cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to); ++ cpuset_update_task_spread_flags(cs, task); ++} + + static void cpuset_attach(struct cgroup_taskset *tset) + { +- /* static buf protected by cpuset_rwsem */ +- static nodemask_t cpuset_attach_nodemask_to; + struct task_struct *task; + struct task_struct *leader; + struct cgroup_subsys_state *css; +@@ -2237,16 +2250,8 @@ static void cpuset_attach(struct cgroup_ + + guarantee_online_mems(cs, &cpuset_attach_nodemask_to); + +- cgroup_taskset_for_each(task, css, tset) { +- /* +- * can_attach beforehand should guarantee that this doesn't +- * fail. TODO: have a better way to handle failure here +- */ +- WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach)); +- +- cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to); +- cpuset_update_task_spread_flags(cs, task); +- } ++ cgroup_taskset_for_each(task, css, tset) ++ cpuset_attach_task(cs, task); + + /* + * Change mm for all threadgroup leaders. This is expensive and may +@@ -2914,11 +2919,34 @@ static void cpuset_bind(struct cgroup_su + */ + static void cpuset_fork(struct task_struct *task) + { +- if (task_css_is_root(task, cpuset_cgrp_id)) ++ struct cpuset *cs; ++ bool same_cs; ++ ++ rcu_read_lock(); ++ cs = task_cs(task); ++ same_cs = (cs == task_cs(current)); ++ rcu_read_unlock(); ++ ++ if (same_cs) { ++ if (cs == &top_cpuset) ++ return; ++ ++ set_cpus_allowed_ptr(task, current->cpus_ptr); ++ task->mems_allowed = current->mems_allowed; + return; ++ } ++ ++ /* CLONE_INTO_CGROUP */ ++ percpu_down_write(&cpuset_rwsem); ++ guarantee_online_mems(cs, &cpuset_attach_nodemask_to); + +- set_cpus_allowed_ptr(task, current->cpus_ptr); +- task->mems_allowed = current->mems_allowed; ++ /* prepare for attach */ ++ if (cs == &top_cpuset) ++ cpumask_copy(cpus_attach, cpu_possible_mask); ++ else ++ guarantee_online_cpus(cs, cpus_attach); ++ cpuset_attach_task(cs, task); ++ percpu_up_write(&cpuset_rwsem); + } + + struct cgroup_subsys cpuset_cgrp_subsys = { diff --git a/queue-5.10/cgroup-cpuset-skip-spread-flags-update-on-v2.patch b/queue-5.10/cgroup-cpuset-skip-spread-flags-update-on-v2.patch new file mode 100644 index 00000000000..fea6ba0abbb --- /dev/null +++ b/queue-5.10/cgroup-cpuset-skip-spread-flags-update-on-v2.patch @@ -0,0 +1,62 @@ +From stable-owner@vger.kernel.org Mon Apr 17 19:21:24 2023 +From: Waiman Long +Date: Mon, 17 Apr 2023 13:19:56 -0400 +Subject: cgroup/cpuset: Skip spread flags update on v2 +To: Greg Kroah-Hartman , stable@vger.kernel.org +Cc: "Tejun Heo" , "Michal Koutný" , "Giuseppe Scrivano" , "Waiman Long" +Message-ID: <20230417171958.3389333-2-longman@redhat.com> + +From: Waiman Long + +commit 18f9a4d47527772515ad6cbdac796422566e6440 upstream. + +Cpuset v2 has no spread flags to set. So we can skip spread +flags update if cpuset v2 is being used. Also change the name to +cpuset_update_task_spread_flags() to indicate that there are multiple +spread flags. + +Signed-off-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman +--- + kernel/cgroup/cpuset.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -424,11 +424,15 @@ static void guarantee_online_mems(struct + /* + * update task's spread flag if cpuset's page/slab spread flag is set + * +- * Call with callback_lock or cpuset_rwsem held. ++ * Call with callback_lock or cpuset_rwsem held. The check can be skipped ++ * if on default hierarchy. + */ +-static void cpuset_update_task_spread_flag(struct cpuset *cs, ++static void cpuset_update_task_spread_flags(struct cpuset *cs, + struct task_struct *tsk) + { ++ if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) ++ return; ++ + if (is_spread_page(cs)) + task_set_spread_page(tsk); + else +@@ -1907,7 +1911,7 @@ static void update_tasks_flags(struct cp + + css_task_iter_start(&cs->css, 0, &it); + while ((task = css_task_iter_next(&it))) +- cpuset_update_task_spread_flag(cs, task); ++ cpuset_update_task_spread_flags(cs, task); + css_task_iter_end(&it); + } + +@@ -2241,7 +2245,7 @@ static void cpuset_attach(struct cgroup_ + WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach)); + + cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to); +- cpuset_update_task_spread_flag(cs, task); ++ cpuset_update_task_spread_flags(cs, task); + } + + /* diff --git a/queue-5.10/coresight-etm4-fix-for-loop-drvdata-nr_addr_cmp-range-bug.patch b/queue-5.10/coresight-etm4-fix-for-loop-drvdata-nr_addr_cmp-range-bug.patch new file mode 100644 index 00000000000..ab3a32da4b9 --- /dev/null +++ b/queue-5.10/coresight-etm4-fix-for-loop-drvdata-nr_addr_cmp-range-bug.patch @@ -0,0 +1,33 @@ +From bf84937e882009075f57fd213836256fc65d96bc Mon Sep 17 00:00:00 2001 +From: Steve Clevenger +Date: Mon, 27 Feb 2023 16:54:32 -0700 +Subject: coresight-etm4: Fix for() loop drvdata->nr_addr_cmp range bug + +From: Steve Clevenger + +commit bf84937e882009075f57fd213836256fc65d96bc upstream. + +In etm4_enable_hw, fix for() loop range to represent address comparator pairs. + +Fixes: 2e1cdfe184b5 ("coresight-etm4x: Adding CoreSight ETM4x driver") +Cc: stable@vger.kernel.org +Signed-off-by: Steve Clevenger +Reviewed-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/4a4ee61ce8ef402615a4528b21a051de3444fb7b.1677540079.git.scclevenger@os.amperecomputing.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -179,7 +179,7 @@ static int etm4_enable_hw(struct etmv4_d + writel_relaxed(config->ss_pe_cmp[i], + drvdata->base + TRCSSPCICRn(i)); + } +- for (i = 0; i < drvdata->nr_addr_cmp; i++) { ++ for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) { + writeq_relaxed(config->addr_val[i], + drvdata->base + TRCACVRn(i)); + writeq_relaxed(config->addr_acc[i], diff --git a/queue-5.10/kbuild-check-config_as_is_llvm-instead-of-llvm_ias.patch b/queue-5.10/kbuild-check-config_as_is_llvm-instead-of-llvm_ias.patch new file mode 100644 index 00000000000..97fd791270b --- /dev/null +++ b/queue-5.10/kbuild-check-config_as_is_llvm-instead-of-llvm_ias.patch @@ -0,0 +1,65 @@ +From stable-owner@vger.kernel.org Wed Mar 29 02:08:43 2023 +From: Nathan Chancellor +Date: Tue, 28 Mar 2023 17:08:31 -0700 +Subject: kbuild: check CONFIG_AS_IS_LLVM instead of LLVM_IAS +To: gregkh@linuxfoundation.org, sashal@kernel.org +Cc: conor@kernel.org, stable@vger.kernel.org, llvm@lists.linux.dev, Masahiro Yamada , Nick Desaulniers , Nathan Chancellor +Message-ID: <20230328-riscv-zifencei-zicsr-5-10-v1-3-bccb3e16dc46@kernel.org> + +From: Masahiro Yamada + +commit 52cc02b910284d6bddba46cce402044ab775f314 upstream. + +LLVM_IAS is the user interface to set the -(no-)integrated-as flag, +and it should be used only for that purpose. + +LLVM_IAS is checked in some places to determine the assembler type, +but it is not precise. + +For example, + + $ make CC=gcc LLVM_IAS=1 + +... will use the GNU assembler (i.e. binutils) since LLVM_IAS=1 is +effective only when $(CC) is clang. + +Of course, 'CC=gcc LLVM_IAS=1' is an odd combination, but the build +system can be more robust against such insane input. + +Commit ba64beb17493a ("kbuild: check the minimum assembler version in +Kconfig") introduced CONFIG_AS_IS_GNU/LLVM, which is more precise +because Kconfig checks the version string from the assembler in use. + +Signed-off-by: Masahiro Yamada +Reviewed-by: Nick Desaulniers +Reviewed-by: Nathan Chancellor +[nathan: Backport to 5.10] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 2 +- + arch/riscv/Makefile | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -851,7 +851,7 @@ else + DEBUG_CFLAGS += -g + endif + +-ifeq ($(LLVM_IAS),1) ++ifdef CONFIG_AS_IS_LLVM + KBUILD_AFLAGS += -g + else + KBUILD_AFLAGS += -Wa,-gdwarf-2 +--- a/arch/riscv/Makefile ++++ b/arch/riscv/Makefile +@@ -40,7 +40,7 @@ ifeq ($(CONFIG_LD_IS_LLD),y) + ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0) + KBUILD_CFLAGS += -mno-relax + KBUILD_AFLAGS += -mno-relax +-ifneq ($(LLVM_IAS),1) ++ifndef CONFIG_AS_IS_LLVM + KBUILD_CFLAGS += -Wa,-mno-relax + KBUILD_AFLAGS += -Wa,-mno-relax + endif diff --git a/queue-5.10/kbuild-check-the-minimum-assembler-version-in-kconfig.patch b/queue-5.10/kbuild-check-the-minimum-assembler-version-in-kconfig.patch new file mode 100644 index 00000000000..1bd70d0140e --- /dev/null +++ b/queue-5.10/kbuild-check-the-minimum-assembler-version-in-kconfig.patch @@ -0,0 +1,240 @@ +From stable-owner@vger.kernel.org Wed Mar 29 02:08:38 2023 +From: Nathan Chancellor +Date: Tue, 28 Mar 2023 17:08:29 -0700 +Subject: kbuild: check the minimum assembler version in Kconfig +To: gregkh@linuxfoundation.org, sashal@kernel.org +Cc: conor@kernel.org, stable@vger.kernel.org, llvm@lists.linux.dev, Masahiro Yamada , Nathan Chancellor +Message-ID: <20230328-riscv-zifencei-zicsr-5-10-v1-1-bccb3e16dc46@kernel.org> + +From: Masahiro Yamada + +commit ba64beb17493a4bfec563100c86a462a15926f24 upstream. + +Documentation/process/changes.rst defines the minimum assembler version +(binutils version), but we have never checked it in the build time. + +Kbuild never invokes 'as' directly because all assembly files in the +kernel tree are *.S, hence must be preprocessed. I do not expect +raw assembly source files (*.s) would be added to the kernel tree. + +Therefore, we always use $(CC) as the assembler driver, and commit +aa824e0c962b ("kbuild: remove AS variable") removed 'AS'. However, +we are still interested in the version of the assembler acting behind. + +As usual, the --version option prints the version string. + + $ as --version | head -n 1 + GNU assembler (GNU Binutils for Ubuntu) 2.35.1 + +But, we do not have $(AS). So, we can add the -Wa prefix so that +$(CC) passes --version down to the backing assembler. + + $ gcc -Wa,--version | head -n 1 + gcc: fatal error: no input files + compilation terminated. + +OK, we need to input something to satisfy gcc. + + $ gcc -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 + GNU assembler (GNU Binutils for Ubuntu) 2.35.1 + +The combination of Clang and GNU assembler works in the same way: + + $ clang -no-integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 + GNU assembler (GNU Binutils for Ubuntu) 2.35.1 + +Clang with the integrated assembler fails like this: + + $ clang -integrated-as -Wa,--version -c -x assembler /dev/null -o /dev/null | head -n 1 + clang: error: unsupported argument '--version' to option 'Wa,' + +For the last case, checking the error message is fragile. If the +proposal for -Wa,--version support [1] is accepted, this may not be +even an error in the future. + +One easy way is to check if -integrated-as is present in the passed +arguments. We did not pass -integrated-as to CLANG_FLAGS before, but +we can make it explicit. + +Nathan pointed out -integrated-as is the default for all of the +architectures/targets that the kernel cares about, but it goes +along with "explicit is better than implicit" policy. [2] + +With all this in my mind, I implemented scripts/as-version.sh to +check the assembler version in Kconfig time. + + $ scripts/as-version.sh gcc + GNU 23501 + $ scripts/as-version.sh clang -no-integrated-as + GNU 23501 + $ scripts/as-version.sh clang -integrated-as + LLVM 0 + +[1]: https://github.com/ClangBuiltLinux/linux/issues/1320 +[2]: https://lore.kernel.org/linux-kbuild/20210307044253.v3h47ucq6ng25iay@archlinux-ax161/ + +Signed-off-by: Masahiro Yamada +Reviewed-by: Nathan Chancellor +[nathan: Backport to 5.10. Drop minimum version checking, as it is not + required in 5.10] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 4 ++ + init/Kconfig | 12 ++++++++ + scripts/Kconfig.include | 6 ++++ + scripts/as-version.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ + scripts/dummy-tools/gcc | 6 ++++ + 5 files changed, 96 insertions(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index 71caf5938361..44d9aff4f66a 100644 +--- a/Makefile ++++ b/Makefile +@@ -580,7 +580,9 @@ endif + ifneq ($(GCC_TOOLCHAIN),) + CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) + endif +-ifneq ($(LLVM_IAS),1) ++ifeq ($(LLVM_IAS),1) ++CLANG_FLAGS += -integrated-as ++else + CLANG_FLAGS += -no-integrated-as + endif + CLANG_FLAGS += -Werror=unknown-warning-option +diff --git a/init/Kconfig b/init/Kconfig +index eba883d6d9ed..9807c66b24bb 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -47,6 +47,18 @@ config CLANG_VERSION + int + default $(shell,$(srctree)/scripts/clang-version.sh $(CC)) + ++config AS_IS_GNU ++ def_bool $(success,test "$(as-name)" = GNU) ++ ++config AS_IS_LLVM ++ def_bool $(success,test "$(as-name)" = LLVM) ++ ++config AS_VERSION ++ int ++ # Use clang version if this is the integrated assembler ++ default CLANG_VERSION if AS_IS_LLVM ++ default $(as-version) ++ + config LLD_VERSION + int + default $(shell,$(srctree)/scripts/lld-version.sh $(LD)) +diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include +index a5fe72c504ff..6d37cb780452 100644 +--- a/scripts/Kconfig.include ++++ b/scripts/Kconfig.include +@@ -42,6 +42,12 @@ $(error-if,$(failure,command -v $(LD)),linker '$(LD)' not found) + # Fail if the linker is gold as it's not capable of linking the kernel proper + $(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supported) + ++# Get the assembler name, version, and error out if it is not supported. ++as-info := $(shell,$(srctree)/scripts/as-version.sh $(CC) $(CLANG_FLAGS)) ++$(error-if,$(success,test -z "$(as-info)"),Sorry$(comma) this assembler is not supported.) ++as-name := $(shell,set -- $(as-info) && echo $1) ++as-version := $(shell,set -- $(as-info) && echo $2) ++ + # machine bit flags + # $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise. + # $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise. +diff --git a/scripts/as-version.sh b/scripts/as-version.sh +new file mode 100755 +index 000000000000..851dcb8a0e68 +--- /dev/null ++++ b/scripts/as-version.sh +@@ -0,0 +1,69 @@ ++#!/bin/sh ++# SPDX-License-Identifier: GPL-2.0-only ++# ++# Print the assembler name and its version in a 5 or 6-digit form. ++# Also, perform the minimum version check. ++# (If it is the integrated assembler, return 0 as the version, and ++# skip the version check.) ++ ++set -e ++ ++# Convert the version string x.y.z to a canonical 5 or 6-digit form. ++get_canonical_version() ++{ ++ IFS=. ++ set -- $1 ++ ++ # If the 2nd or 3rd field is missing, fill it with a zero. ++ # ++ # The 4th field, if present, is ignored. ++ # This occurs in development snapshots as in 2.35.1.20201116 ++ echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0})) ++} ++ ++# Clang fails to handle -Wa,--version unless -no-integrated-as is given. ++# We check -(f)integrated-as, expecting it is explicitly passed in for the ++# integrated assembler case. ++check_integrated_as() ++{ ++ while [ $# -gt 0 ]; do ++ if [ "$1" = -integrated-as -o "$1" = -fintegrated-as ]; then ++ # For the intergrated assembler, we do not check the ++ # version here. It is the same as the clang version, and ++ # it has been already checked by scripts/cc-version.sh. ++ echo LLVM 0 ++ exit 0 ++ fi ++ shift ++ done ++} ++ ++check_integrated_as "$@" ++ ++orig_args="$@" ++ ++# Get the first line of the --version output. ++IFS=' ++' ++set -- $(LC_ALL=C "$@" -Wa,--version -c -x assembler /dev/null -o /dev/null 2>/dev/null) ++ ++# Split the line on spaces. ++IFS=' ' ++set -- $1 ++ ++if [ "$1" = GNU -a "$2" = assembler ]; then ++ shift $(($# - 1)) ++ version=$1 ++ name=GNU ++else ++ echo "$orig_args: unknown assembler invoked" >&2 ++ exit 1 ++fi ++ ++# Some distributions append a package release number, as in 2.34-4.fc32 ++# Trim the hyphen and any characters that follow. ++version=${version%-*} ++ ++cversion=$(get_canonical_version $version) ++ ++echo $name $cversion +diff --git a/scripts/dummy-tools/gcc b/scripts/dummy-tools/gcc +index 346757a87dbc..485427f40dba 100755 +--- a/scripts/dummy-tools/gcc ++++ b/scripts/dummy-tools/gcc +@@ -67,6 +67,12 @@ if arg_contain -E "$@"; then + fi + fi + ++# To set CONFIG_AS_IS_GNU ++if arg_contain -Wa,--version "$@"; then ++ echo "GNU assembler (scripts/dummy-tools) 2.50" ++ exit 0 ++fi ++ + if arg_contain -S "$@"; then + # For scripts/gcc-x86-*-has-stack-protector.sh + if arg_contain -fstack-protector "$@"; then + +-- +2.40.0 + diff --git a/queue-5.10/kbuild-switch-to-f-variants-of-integrated-assembler-flag.patch b/queue-5.10/kbuild-switch-to-f-variants-of-integrated-assembler-flag.patch new file mode 100644 index 00000000000..402636c4ad3 --- /dev/null +++ b/queue-5.10/kbuild-switch-to-f-variants-of-integrated-assembler-flag.patch @@ -0,0 +1,69 @@ +From stable-owner@vger.kernel.org Wed Mar 29 02:08:38 2023 +From: Nathan Chancellor +Date: Tue, 28 Mar 2023 17:08:30 -0700 +Subject: kbuild: Switch to 'f' variants of integrated assembler flag +To: gregkh@linuxfoundation.org, sashal@kernel.org +Cc: conor@kernel.org, stable@vger.kernel.org, llvm@lists.linux.dev, Nick Desaulniers , Nathan Chancellor , Masahiro Yamada +Message-ID: <20230328-riscv-zifencei-zicsr-5-10-v1-2-bccb3e16dc46@kernel.org> + +From: Nathan Chancellor + +commit 2185a7e4b0ade86c2c57fc63d4a7535c40254bd0 upstream. + +It has been brought up a few times in various code reviews that clang +3.5 introduced -f{,no-}integrated-as as the preferred way to enable and +disable the integrated assembler, mentioning that -{no-,}integrated-as +are now considered legacy flags. + +Switch the kernel over to using those variants in case there is ever a +time where clang decides to remove the non-'f' variants of the flag. + +Also, fix a typo in a comment ("intergrated" -> "integrated"). + +Link: https://releases.llvm.org/3.5.0/tools/clang/docs/ReleaseNotes.html#new-compiler-flags +Reviewed-by: Nick Desaulniers +Signed-off-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +[nathan: Backport to 5.10] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + Makefile | 4 ++-- + scripts/as-version.sh | 8 ++++---- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -581,9 +581,9 @@ ifneq ($(GCC_TOOLCHAIN),) + CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) + endif + ifeq ($(LLVM_IAS),1) +-CLANG_FLAGS += -integrated-as ++CLANG_FLAGS += -fintegrated-as + else +-CLANG_FLAGS += -no-integrated-as ++CLANG_FLAGS += -fno-integrated-as + endif + CLANG_FLAGS += -Werror=unknown-warning-option + KBUILD_CFLAGS += $(CLANG_FLAGS) +--- a/scripts/as-version.sh ++++ b/scripts/as-version.sh +@@ -21,14 +21,14 @@ get_canonical_version() + echo $((10000 * $1 + 100 * ${2:-0} + ${3:-0})) + } + +-# Clang fails to handle -Wa,--version unless -no-integrated-as is given. +-# We check -(f)integrated-as, expecting it is explicitly passed in for the ++# Clang fails to handle -Wa,--version unless -fno-integrated-as is given. ++# We check -fintegrated-as, expecting it is explicitly passed in for the + # integrated assembler case. + check_integrated_as() + { + while [ $# -gt 0 ]; do +- if [ "$1" = -integrated-as -o "$1" = -fintegrated-as ]; then +- # For the intergrated assembler, we do not check the ++ if [ "$1" = -fintegrated-as ]; then ++ # For the integrated assembler, we do not check the + # version here. It is the same as the clang version, and + # it has been already checked by scripts/cc-version.sh. + echo LLVM 0 diff --git a/queue-5.10/riscv-handle-zicsr-zifencei-issues-between-clang-and-binutils.patch b/queue-5.10/riscv-handle-zicsr-zifencei-issues-between-clang-and-binutils.patch new file mode 100644 index 00000000000..b8f4a8ba7da --- /dev/null +++ b/queue-5.10/riscv-handle-zicsr-zifencei-issues-between-clang-and-binutils.patch @@ -0,0 +1,126 @@ +From stable-owner@vger.kernel.org Wed Mar 29 02:08:41 2023 +From: Nathan Chancellor +Date: Tue, 28 Mar 2023 17:08:32 -0700 +Subject: riscv: Handle zicsr/zifencei issues between clang and binutils +To: gregkh@linuxfoundation.org, sashal@kernel.org +Cc: conor@kernel.org, stable@vger.kernel.org, llvm@lists.linux.dev, Conor Dooley , Nathan Chancellor , Palmer Dabbelt +Message-ID: <20230328-riscv-zifencei-zicsr-5-10-v1-4-bccb3e16dc46@kernel.org> + +From: Nathan Chancellor + +commit e89c2e815e76471cb507bd95728bf26da7976430 upstream. + +There are two related issues that appear in certain combinations with +clang and GNU binutils. + +The first occurs when a version of clang that supports zicsr or zifencei +via '-march=' [1] (i.e, >= 17.x) is used in combination with a version +of GNU binutils that do not recognize zicsr and zifencei in the +'-march=' value (i.e., < 2.36): + + riscv64-linux-gnu-ld: -march=rv64i2p0_m2p0_a2p0_c2p0_zicsr2p0_zifencei2p0: Invalid or unknown z ISA extension: 'zifencei' + riscv64-linux-gnu-ld: failed to merge target specific data of file fs/efivarfs/file.o + riscv64-linux-gnu-ld: -march=rv64i2p0_m2p0_a2p0_c2p0_zicsr2p0_zifencei2p0: Invalid or unknown z ISA extension: 'zifencei' + riscv64-linux-gnu-ld: failed to merge target specific data of file fs/efivarfs/super.o + +The second occurs when a version of clang that does not support zicsr or +zifencei via '-march=' (i.e., <= 16.x) is used in combination with a +version of GNU as that defaults to a newer ISA base spec, which requires +specifying zicsr and zifencei in the '-march=' value explicitly (i.e, >= +2.38): + + ../arch/riscv/kernel/kexec_relocate.S: Assembler messages: + ../arch/riscv/kernel/kexec_relocate.S:147: Error: unrecognized opcode `fence.i', extension `zifencei' required + clang-12: error: assembler command failed with exit code 1 (use -v to see invocation) + +This is the same issue addressed by commit 6df2a016c0c8 ("riscv: fix +build with binutils 2.38") (see [2] for additional information) but +older versions of clang miss out on it because the cc-option check +fails: + + clang-12: error: invalid arch name 'rv64imac_zicsr_zifencei', unsupported standard user-level extension 'zicsr' + clang-12: error: invalid arch name 'rv64imac_zicsr_zifencei', unsupported standard user-level extension 'zicsr' + +To resolve the first issue, only attempt to add zicsr and zifencei to +the march string when using the GNU assembler 2.38 or newer, which is +when the default ISA spec was updated, requiring these extensions to be +specified explicitly. LLVM implements an older version of the base +specification for all currently released versions, so these instructions +are available as part of the 'i' extension. If LLVM's implementation is +updated in the future, a CONFIG_AS_IS_LLVM condition can be added to +CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. + +To resolve the second issue, use version 2.2 of the base ISA spec when +using an older version of clang that does not support zicsr or zifencei +via '-march=', as that is the spec version most compatible with the one +clang/LLVM implements and avoids the need to specify zicsr and zifencei +explicitly due to still being a part of 'i'. + +[1]: https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16 +[2]: https://lore.kernel.org/ZAxT7T9Xy1Fo3d5W@aurel32.net/ + +Cc: stable@vger.kernel.org +Link: https://github.com/ClangBuiltLinux/linux/issues/1808 +Co-developed-by: Conor Dooley +Signed-off-by: Conor Dooley +Signed-off-by: Nathan Chancellor +Acked-by: Conor Dooley +Link: https://lore.kernel.org/r/20230313-riscv-zicsr-zifencei-fiasco-v1-1-dd1b7840a551@kernel.org +Signed-off-by: Palmer Dabbelt +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + arch/riscv/Kconfig | 22 ++++++++++++++++++++++ + arch/riscv/Makefile | 10 ++++++---- + 2 files changed, 28 insertions(+), 4 deletions(-) + +--- a/arch/riscv/Kconfig ++++ b/arch/riscv/Kconfig +@@ -331,6 +331,28 @@ config RISCV_BASE_PMU + + endmenu + ++config TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI ++ def_bool y ++ # https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=aed44286efa8ae8717a77d94b51ac3614e2ca6dc ++ depends on AS_IS_GNU && AS_VERSION >= 23800 ++ help ++ Newer binutils versions default to ISA spec version 20191213 which ++ moves some instructions from the I extension to the Zicsr and Zifencei ++ extensions. ++ ++config TOOLCHAIN_NEEDS_OLD_ISA_SPEC ++ def_bool y ++ depends on TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI ++ # https://github.com/llvm/llvm-project/commit/22e199e6afb1263c943c0c0d4498694e15bf8a16 ++ depends on CC_IS_CLANG && CLANG_VERSION < 170000 ++ help ++ Certain versions of clang do not support zicsr and zifencei via -march ++ but newer versions of binutils require it for the reasons noted in the ++ help text of CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI. This ++ option causes an older ISA spec compatible with these older versions ++ of clang to be passed to GAS, which has the same result as passing zicsr ++ and zifencei to -march. ++ + config FPU + bool "FPU support" + default y +--- a/arch/riscv/Makefile ++++ b/arch/riscv/Makefile +@@ -53,10 +53,12 @@ riscv-march-$(CONFIG_ARCH_RV64I) := rv64 + riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd + riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c + +-# Newer binutils versions default to ISA spec version 20191213 which moves some +-# instructions from the I extension to the Zicsr and Zifencei extensions. +-toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei) +-riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei ++ifdef CONFIG_TOOLCHAIN_NEEDS_OLD_ISA_SPEC ++KBUILD_CFLAGS += -Wa,-misa-spec=2.2 ++KBUILD_AFLAGS += -Wa,-misa-spec=2.2 ++else ++riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei ++endif + + KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) + KBUILD_AFLAGS += -march=$(riscv-march-y) diff --git a/queue-5.10/series b/queue-5.10/series index aff95ea84ff..4d014179d2d 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -108,3 +108,13 @@ sched-fair-move-calculate-of-avg_load-to-a-better-lo.patch sched-fair-fix-imbalance-overflow.patch x86-rtc-remove-__init-for-runtime-functions.patch i2c-ocores-generate-stop-condition-after-timeout-in-.patch +cgroup-cpuset-change-references-of-cpuset_mutex-to-cpuset_rwsem.patch +cgroup-cpuset-skip-spread-flags-update-on-v2.patch +cgroup-cpuset-make-cpuset_fork-handle-clone_into_cgroup-properly.patch +cgroup-cpuset-add-cpuset_can_fork-and-cpuset_cancel_fork-methods.patch +watchdog-sbsa_wdog-make-sure-the-timeout-programming-is-within-the-limits.patch +coresight-etm4-fix-for-loop-drvdata-nr_addr_cmp-range-bug.patch +kbuild-check-the-minimum-assembler-version-in-kconfig.patch +kbuild-switch-to-f-variants-of-integrated-assembler-flag.patch +kbuild-check-config_as_is_llvm-instead-of-llvm_ias.patch +riscv-handle-zicsr-zifencei-issues-between-clang-and-binutils.patch diff --git a/queue-5.10/watchdog-sbsa_wdog-make-sure-the-timeout-programming-is-within-the-limits.patch b/queue-5.10/watchdog-sbsa_wdog-make-sure-the-timeout-programming-is-within-the-limits.patch new file mode 100644 index 00000000000..ca773763ac4 --- /dev/null +++ b/queue-5.10/watchdog-sbsa_wdog-make-sure-the-timeout-programming-is-within-the-limits.patch @@ -0,0 +1,36 @@ +From 000987a38b53c172f435142a4026dd71378ca464 Mon Sep 17 00:00:00 2001 +From: George Cherian +Date: Thu, 9 Feb 2023 02:11:17 +0000 +Subject: watchdog: sbsa_wdog: Make sure the timeout programming is within the limits + +From: George Cherian + +commit 000987a38b53c172f435142a4026dd71378ca464 upstream. + +Make sure to honour the max_hw_heartbeat_ms while programming the timeout +value to WOR. Clamp the timeout passed to sbsa_gwdt_set_timeout() to +make sure the programmed value is within the permissible range. + +Fixes: abd3ac7902fb ("watchdog: sbsa: Support architecture version 1") + +Signed-off-by: George Cherian +Reviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/20230209021117.1512097-1-george.cherian@marvell.com +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Tyler Hicks (Microsoft) +Signed-off-by: Greg Kroah-Hartman +--- + drivers/watchdog/sbsa_gwdt.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/watchdog/sbsa_gwdt.c ++++ b/drivers/watchdog/sbsa_gwdt.c +@@ -121,6 +121,7 @@ static int sbsa_gwdt_set_timeout(struct + struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd); + + wdd->timeout = timeout; ++ timeout = clamp_t(unsigned int, timeout, 1, wdd->max_hw_heartbeat_ms / 1000); + + if (action) + writel(gwdt->clk * timeout,