From 507b6f0198edd219162acee181476a714a07c9b5 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 15 Jun 2023 10:25:21 -0400 Subject: [PATCH] Fixes for 6.3 Signed-off-by: Sasha Levin --- ...-put-cset-in-cgroup_css_set_put_fork.patch | 86 +++ ...e-cgroup_lock-cgroup_unlock-wrappers.patch | 543 ++++++++++++++++++ ...ng-cpus_read_-lock-unlock-in-cgroup_.patch | 78 +++ ...et-rid-of-hardcoded-register-offsets.patch | 328 +++++++++++ ...mbd-validate-smb-request-protocol-id.patch | 88 +++ ...ix-the-base-address-used-for-accessi.patch | 268 +++++++++ queue-6.3/series | 7 + ...ch-to-kernel_cs-as-soon-as-new-gdt-i.patch | 80 +++ 8 files changed, 1478 insertions(+) create mode 100644 queue-6.3/cgroup-always-put-cset-in-cgroup_css_set_put_fork.patch create mode 100644 queue-6.3/cgroup-bpf-use-cgroup_lock-cgroup_unlock-wrappers.patch create mode 100644 queue-6.3/cgroup-fix-missing-cpus_read_-lock-unlock-in-cgroup_.patch create mode 100644 queue-6.3/edac-qcom-get-rid-of-hardcoded-register-offsets.patch create mode 100644 queue-6.3/ksmbd-validate-smb-request-protocol-id.patch create mode 100644 queue-6.3/qcom-llcc-edac-fix-the-base-address-used-for-accessi.patch create mode 100644 queue-6.3/series create mode 100644 queue-6.3/x86-head-64-switch-to-kernel_cs-as-soon-as-new-gdt-i.patch diff --git a/queue-6.3/cgroup-always-put-cset-in-cgroup_css_set_put_fork.patch b/queue-6.3/cgroup-always-put-cset-in-cgroup_css_set_put_fork.patch new file mode 100644 index 00000000000..1fe32a60969 --- /dev/null +++ b/queue-6.3/cgroup-always-put-cset-in-cgroup_css_set_put_fork.patch @@ -0,0 +1,86 @@ +From 1a1986781f4a86ea4a6975b454d70dd368584db2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 May 2023 19:29:53 +0000 +Subject: cgroup: always put cset in cgroup_css_set_put_fork + +From: John Sperbeck + +[ Upstream commit 2bd110339288c18823dcace602b63b0d8627e520 ] + +A successful call to cgroup_css_set_fork() will always have taken +a ref on kargs->cset (regardless of CLONE_INTO_CGROUP), so always +do a corresponding put in cgroup_css_set_put_fork(). + +Without this, a cset and its contained css structures will be +leaked for some fork failures. The following script reproduces +the leak for a fork failure due to exceeding pids.max in the +pids controller. A similar thing can happen if we jump to the +bad_fork_cancel_cgroup label in copy_process(). + +[ -z "$1" ] && echo "Usage $0 pids-root" && exit 1 +PID_ROOT=$1 +CGROUP=$PID_ROOT/foo + +[ -e $CGROUP ] && rmdir -f $CGROUP +mkdir $CGROUP +echo 5 > $CGROUP/pids.max +echo $$ > $CGROUP/cgroup.procs + +fork_bomb() +{ + set -e + for i in $(seq 10); do + /bin/sleep 3600 & + done +} + +(fork_bomb) & +wait +echo $$ > $PID_ROOT/cgroup.procs +kill $(cat $CGROUP/cgroup.procs) +rmdir $CGROUP + +Fixes: ef2c41cf38a7 ("clone3: allow spawning processes into cgroups") +Cc: stable@vger.kernel.org # v5.7+ +Signed-off-by: John Sperbeck +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cgroup.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 83ea13f2ccb1d..fd57c1dca1ccf 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -6476,19 +6476,18 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) + static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs) + __releases(&cgroup_threadgroup_rwsem) __releases(&cgroup_mutex) + { ++ struct cgroup *cgrp = kargs->cgrp; ++ struct css_set *cset = kargs->cset; ++ + cgroup_threadgroup_change_end(current); + +- if (kargs->flags & CLONE_INTO_CGROUP) { +- struct cgroup *cgrp = kargs->cgrp; +- struct css_set *cset = kargs->cset; ++ if (cset) { ++ put_css_set(cset); ++ kargs->cset = NULL; ++ } + ++ if (kargs->flags & CLONE_INTO_CGROUP) { + cgroup_unlock(); +- +- if (cset) { +- put_css_set(cset); +- kargs->cset = NULL; +- } +- + if (cgrp) { + cgroup_put(cgrp); + kargs->cgrp = NULL; +-- +2.39.2 + diff --git a/queue-6.3/cgroup-bpf-use-cgroup_lock-cgroup_unlock-wrappers.patch b/queue-6.3/cgroup-bpf-use-cgroup_lock-cgroup_unlock-wrappers.patch new file mode 100644 index 00000000000..385c9da6118 --- /dev/null +++ b/queue-6.3/cgroup-bpf-use-cgroup_lock-cgroup_unlock-wrappers.patch @@ -0,0 +1,543 @@ +From 1ef2663d1a9ba8728be5c0f49d8de11593cd9dee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Mar 2023 15:23:10 +0530 +Subject: cgroup: bpf: use cgroup_lock()/cgroup_unlock() wrappers + +From: Kamalesh Babulal + +[ Upstream commit 4cdb91b0dea7d7f59fa84a13c7753cd434fdedcf ] + +Replace mutex_[un]lock() with cgroup_[un]lock() wrappers to stay +consistent across cgroup core and other subsystem code, while +operating on the cgroup_mutex. + +Signed-off-by: Kamalesh Babulal +Acked-by: Alexei Starovoitov +Reviewed-by: Christian Brauner +Signed-off-by: Tejun Heo +Stable-dep-of: 2bd110339288 ("cgroup: always put cset in cgroup_css_set_put_fork") +Signed-off-by: Sasha Levin +--- + kernel/bpf/cgroup.c | 38 ++++++++++++------------ + kernel/bpf/cgroup_iter.c | 4 +-- + kernel/bpf/local_storage.c | 4 +-- + kernel/cgroup/cgroup-v1.c | 16 +++++----- + kernel/cgroup/cgroup.c | 60 +++++++++++++++++++------------------- + 5 files changed, 61 insertions(+), 61 deletions(-) + +diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c +index 819f011f0a9cd..b86b907e566ca 100644 +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -173,11 +173,11 @@ void bpf_cgroup_atype_put(int cgroup_atype) + { + int i = cgroup_atype - CGROUP_LSM_START; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + if (--cgroup_lsm_atype[i].refcnt <= 0) + cgroup_lsm_atype[i].attach_btf_id = 0; + WARN_ON_ONCE(cgroup_lsm_atype[i].refcnt < 0); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + } + #else + static enum cgroup_bpf_attach_type +@@ -282,7 +282,7 @@ static void cgroup_bpf_release(struct work_struct *work) + + unsigned int atype; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + for (atype = 0; atype < ARRAY_SIZE(cgrp->bpf.progs); atype++) { + struct hlist_head *progs = &cgrp->bpf.progs[atype]; +@@ -315,7 +315,7 @@ static void cgroup_bpf_release(struct work_struct *work) + bpf_cgroup_storage_free(storage); + } + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) + cgroup_bpf_put(p); +@@ -729,9 +729,9 @@ static int cgroup_bpf_attach(struct cgroup *cgrp, + { + int ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + ret = __cgroup_bpf_attach(cgrp, prog, replace_prog, link, type, flags); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -831,7 +831,7 @@ static int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *new_prog, + + cg_link = container_of(link, struct bpf_cgroup_link, link); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + /* link might have been auto-released by dying cgroup, so fail */ + if (!cg_link->cgroup) { + ret = -ENOLINK; +@@ -843,7 +843,7 @@ static int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *new_prog, + } + ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog); + out_unlock: +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -1009,9 +1009,9 @@ static int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, + { + int ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + ret = __cgroup_bpf_detach(cgrp, prog, NULL, type); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -1120,9 +1120,9 @@ static int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, + { + int ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + ret = __cgroup_bpf_query(cgrp, attr, uattr); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -1189,11 +1189,11 @@ static void bpf_cgroup_link_release(struct bpf_link *link) + if (!cg_link->cgroup) + return; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + /* re-check cgroup under lock again */ + if (!cg_link->cgroup) { +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return; + } + +@@ -1205,7 +1205,7 @@ static void bpf_cgroup_link_release(struct bpf_link *link) + cg = cg_link->cgroup; + cg_link->cgroup = NULL; + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + cgroup_put(cg); + } +@@ -1232,10 +1232,10 @@ static void bpf_cgroup_link_show_fdinfo(const struct bpf_link *link, + container_of(link, struct bpf_cgroup_link, link); + u64 cg_id = 0; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + if (cg_link->cgroup) + cg_id = cgroup_id(cg_link->cgroup); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + seq_printf(seq, + "cgroup_id:\t%llu\n" +@@ -1251,10 +1251,10 @@ static int bpf_cgroup_link_fill_link_info(const struct bpf_link *link, + container_of(link, struct bpf_cgroup_link, link); + u64 cg_id = 0; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + if (cg_link->cgroup) + cg_id = cgroup_id(cg_link->cgroup); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + info->cgroup.cgroup_id = cg_id; + info->cgroup.attach_type = cg_link->type; +diff --git a/kernel/bpf/cgroup_iter.c b/kernel/bpf/cgroup_iter.c +index 06989d2788465..810378f04fbca 100644 +--- a/kernel/bpf/cgroup_iter.c ++++ b/kernel/bpf/cgroup_iter.c +@@ -58,7 +58,7 @@ static void *cgroup_iter_seq_start(struct seq_file *seq, loff_t *pos) + { + struct cgroup_iter_priv *p = seq->private; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + /* cgroup_iter doesn't support read across multiple sessions. */ + if (*pos > 0) { +@@ -89,7 +89,7 @@ static void cgroup_iter_seq_stop(struct seq_file *seq, void *v) + { + struct cgroup_iter_priv *p = seq->private; + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + /* pass NULL to the prog for post-processing */ + if (!v) { +diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c +index 66d8ce2ab5b34..d6f3b7ead2c09 100644 +--- a/kernel/bpf/local_storage.c ++++ b/kernel/bpf/local_storage.c +@@ -333,14 +333,14 @@ static void cgroup_storage_map_free(struct bpf_map *_map) + struct list_head *storages = &map->list; + struct bpf_cgroup_storage *storage, *stmp; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + list_for_each_entry_safe(storage, stmp, storages, list_map) { + bpf_cgroup_storage_unlink(storage); + bpf_cgroup_storage_free(storage); + } + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + WARN_ON(!RB_EMPTY_ROOT(&map->root)); + WARN_ON(!list_empty(&map->list)); +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index 52bb5a74a23b9..aeef06c465ef1 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -58,7 +58,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) + struct cgroup_root *root; + int retval = 0; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + cgroup_attach_lock(true); + for_each_root(root) { + struct cgroup *from_cgrp; +@@ -72,7 +72,7 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk) + break; + } + cgroup_attach_unlock(true); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + return retval; + } +@@ -106,7 +106,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) + if (ret) + return ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + percpu_down_write(&cgroup_threadgroup_rwsem); + +@@ -145,7 +145,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) + out_err: + cgroup_migrate_finish(&mgctx); + percpu_up_write(&cgroup_threadgroup_rwsem); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -847,13 +847,13 @@ static int cgroup1_rename(struct kernfs_node *kn, struct kernfs_node *new_parent + kernfs_break_active_protection(new_parent); + kernfs_break_active_protection(kn); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + ret = kernfs_rename(kn, new_parent, new_name_str); + if (!ret) + TRACE_CGROUP_PATH(rename, cgrp); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + kernfs_unbreak_active_protection(kn); + kernfs_unbreak_active_protection(new_parent); +@@ -1119,7 +1119,7 @@ int cgroup1_reconfigure(struct fs_context *fc) + trace_cgroup_remount(root); + + out_unlock: +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -1246,7 +1246,7 @@ int cgroup1_get_tree(struct fs_context *fc) + if (!ret && !percpu_ref_tryget_live(&ctx->root->cgrp.self.refcnt)) + ret = 1; /* restart */ + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + if (!ret) + ret = cgroup_do_get_tree(fc); +diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c +index 935e8121b21e6..83ea13f2ccb1d 100644 +--- a/kernel/cgroup/cgroup.c ++++ b/kernel/cgroup/cgroup.c +@@ -1391,7 +1391,7 @@ static void cgroup_destroy_root(struct cgroup_root *root) + cgroup_favor_dynmods(root, false); + cgroup_exit_root_id(root); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + cgroup_rstat_exit(cgrp); + kernfs_destroy_root(root->kf_root); +@@ -1625,7 +1625,7 @@ void cgroup_kn_unlock(struct kernfs_node *kn) + else + cgrp = kn->parent->priv; + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + kernfs_unbreak_active_protection(kn); + cgroup_put(cgrp); +@@ -1670,7 +1670,7 @@ struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn, bool drain_offline) + if (drain_offline) + cgroup_lock_and_drain_offline(cgrp); + else +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + if (!cgroup_is_dead(cgrp)) + return cgrp; +@@ -2167,13 +2167,13 @@ int cgroup_do_get_tree(struct fs_context *fc) + struct super_block *sb = fc->root->d_sb; + struct cgroup *cgrp; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + spin_lock_irq(&css_set_lock); + + cgrp = cset_cgroup_from_root(ctx->ns->root_cset, ctx->root); + + spin_unlock_irq(&css_set_lock); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + nsdentry = kernfs_node_dentry(cgrp->kn, sb); + dput(fc->root); +@@ -2356,13 +2356,13 @@ int cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen, + { + int ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + spin_lock_irq(&css_set_lock); + + ret = cgroup_path_ns_locked(cgrp, buf, buflen, ns); + + spin_unlock_irq(&css_set_lock); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + return ret; + } +@@ -2388,7 +2388,7 @@ int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) + int hierarchy_id = 1; + int ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + spin_lock_irq(&css_set_lock); + + root = idr_get_next(&cgroup_hierarchy_idr, &hierarchy_id); +@@ -2402,7 +2402,7 @@ int task_cgroup_path(struct task_struct *task, char *buf, size_t buflen) + } + + spin_unlock_irq(&css_set_lock); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + EXPORT_SYMBOL_GPL(task_cgroup_path); +@@ -3111,7 +3111,7 @@ void cgroup_lock_and_drain_offline(struct cgroup *cgrp) + int ssid; + + restart: +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) { + for_each_subsys(ss, ssid) { +@@ -3125,7 +3125,7 @@ void cgroup_lock_and_drain_offline(struct cgroup *cgrp) + prepare_to_wait(&dsct->offline_waitq, &wait, + TASK_UNINTERRUPTIBLE); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + schedule(); + finish_wait(&dsct->offline_waitq, &wait); + +@@ -4374,9 +4374,9 @@ int cgroup_rm_cftypes(struct cftype *cfts) + if (!(cfts[0].flags & __CFTYPE_ADDED)) + return -ENOENT; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + ret = cgroup_rm_cftypes_locked(cfts); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -4408,14 +4408,14 @@ static int cgroup_add_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) + if (ret) + return ret; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + list_add_tail(&cfts->node, &ss->cfts); + ret = cgroup_apply_cftypes(cfts, true); + if (ret) + cgroup_rm_cftypes_locked(cfts); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + return ret; + } + +@@ -5385,7 +5385,7 @@ static void css_release_work_fn(struct work_struct *work) + struct cgroup_subsys *ss = css->ss; + struct cgroup *cgrp = css->cgroup; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + css->flags |= CSS_RELEASED; + list_del_rcu(&css->sibling); +@@ -5426,7 +5426,7 @@ static void css_release_work_fn(struct work_struct *work) + NULL); + } + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + INIT_RCU_WORK(&css->destroy_rwork, css_free_rwork_fn); + queue_rcu_work(cgroup_destroy_wq, &css->destroy_rwork); +@@ -5774,7 +5774,7 @@ static void css_killed_work_fn(struct work_struct *work) + struct cgroup_subsys_state *css = + container_of(work, struct cgroup_subsys_state, destroy_work); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + do { + offline_css(css); +@@ -5783,7 +5783,7 @@ static void css_killed_work_fn(struct work_struct *work) + css = css->parent; + } while (css && atomic_dec_and_test(&css->online_cnt)); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + } + + /* css kill confirmation processing requires process context, bounce */ +@@ -5967,7 +5967,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early) + + pr_debug("Initializing cgroup subsys %s\n", ss->name); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + idr_init(&ss->css_idr); + INIT_LIST_HEAD(&ss->cfts); +@@ -6011,7 +6011,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early) + + BUG_ON(online_css(css)); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + } + + /** +@@ -6071,7 +6071,7 @@ int __init cgroup_init(void) + + get_user_ns(init_cgroup_ns.user_ns); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + /* + * Add init_css_set to the hash table so that dfl_root can link to +@@ -6082,7 +6082,7 @@ int __init cgroup_init(void) + + BUG_ON(cgroup_setup_root(&cgrp_dfl_root, 0)); + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + for_each_subsys(ss, ssid) { + if (ss->early_init) { +@@ -6134,9 +6134,9 @@ int __init cgroup_init(void) + if (ss->bind) + ss->bind(init_css_set.subsys[ssid]); + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + css_populate_dir(init_css_set.subsys[ssid]); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + } + + /* init_css_set.subsys[] has been updated, re-hash */ +@@ -6241,7 +6241,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, + if (!buf) + goto out; + +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + spin_lock_irq(&css_set_lock); + + for_each_root(root) { +@@ -6296,7 +6296,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns, + retval = 0; + out_unlock: + spin_unlock_irq(&css_set_lock); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + kfree(buf); + out: + return retval; +@@ -6380,7 +6380,7 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) + struct file *f; + + if (kargs->flags & CLONE_INTO_CGROUP) +- mutex_lock(&cgroup_mutex); ++ cgroup_lock(); + + cgroup_threadgroup_change_begin(current); + +@@ -6455,7 +6455,7 @@ static int cgroup_css_set_fork(struct kernel_clone_args *kargs) + + err: + cgroup_threadgroup_change_end(current); +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + if (f) + fput(f); + if (dst_cgrp) +@@ -6482,7 +6482,7 @@ static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs) + struct cgroup *cgrp = kargs->cgrp; + struct css_set *cset = kargs->cset; + +- mutex_unlock(&cgroup_mutex); ++ cgroup_unlock(); + + if (cset) { + put_css_set(cset); +-- +2.39.2 + diff --git a/queue-6.3/cgroup-fix-missing-cpus_read_-lock-unlock-in-cgroup_.patch b/queue-6.3/cgroup-fix-missing-cpus_read_-lock-unlock-in-cgroup_.patch new file mode 100644 index 00000000000..dedaf53589c --- /dev/null +++ b/queue-6.3/cgroup-fix-missing-cpus_read_-lock-unlock-in-cgroup_.patch @@ -0,0 +1,78 @@ +From 120ed517f9f53e00f50e37e881040813b9f92374 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 07:45:45 +0000 +Subject: cgroup: fix missing cpus_read_{lock,unlock}() in + cgroup_transfer_tasks() + +From: Qi Zheng + +[ Upstream commit ab1de7ead871ebe6d12a774c3c25de0388cde082 ] + +The commit 4f7e7236435c ("cgroup: Fix threadgroup_rwsem <-> cpus_read_lock() +deadlock") fixed the deadlock between cgroup_threadgroup_rwsem and +cpus_read_lock() by introducing cgroup_attach_{lock,unlock}() and removing +cpus_read_{lock,unlock}() from cpuset_attach(). But cgroup_transfer_tasks() +was missed and not handled, which will cause th following warning: + + WARNING: CPU: 0 PID: 589 at kernel/cpu.c:526 lockdep_assert_cpus_held+0x32/0x40 + CPU: 0 PID: 589 Comm: kworker/1:4 Not tainted 6.4.0-rc2-next-20230517 #50 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 + Workqueue: events cpuset_hotplug_workfn + RIP: 0010:lockdep_assert_cpus_held+0x32/0x40 + <...> + Call Trace: + + cpuset_attach+0x40/0x240 + cgroup_migrate_execute+0x452/0x5e0 + ? _raw_spin_unlock_irq+0x28/0x40 + cgroup_transfer_tasks+0x1f3/0x360 + ? find_held_lock+0x32/0x90 + ? cpuset_hotplug_workfn+0xc81/0xed0 + cpuset_hotplug_workfn+0xcb1/0xed0 + ? process_one_work+0x248/0x5b0 + process_one_work+0x2b9/0x5b0 + worker_thread+0x56/0x3b0 + ? process_one_work+0x5b0/0x5b0 + kthread+0xf1/0x120 + ? kthread_complete_and_exit+0x20/0x20 + ret_from_fork+0x1f/0x30 + + +So just use the cgroup_attach_{lock,unlock}() helper to fix it. + +Reported-by: Zhao Gongyi +Signed-off-by: Qi Zheng +Acked-by: Muchun Song +Fixes: 05c7b7a92cc8 ("cgroup/cpuset: Fix a race between cpuset_attach() and cpu hotplug") +Cc: stable@vger.kernel.org # v5.17+ +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cgroup-v1.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c +index aeef06c465ef1..5407241dbb45f 100644 +--- a/kernel/cgroup/cgroup-v1.c ++++ b/kernel/cgroup/cgroup-v1.c +@@ -108,7 +108,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) + + cgroup_lock(); + +- percpu_down_write(&cgroup_threadgroup_rwsem); ++ cgroup_attach_lock(true); + + /* all tasks in @from are being moved, all csets are source */ + spin_lock_irq(&css_set_lock); +@@ -144,7 +144,7 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from) + } while (task && !ret); + out_err: + cgroup_migrate_finish(&mgctx); +- percpu_up_write(&cgroup_threadgroup_rwsem); ++ cgroup_attach_unlock(true); + cgroup_unlock(); + return ret; + } +-- +2.39.2 + diff --git a/queue-6.3/edac-qcom-get-rid-of-hardcoded-register-offsets.patch b/queue-6.3/edac-qcom-get-rid-of-hardcoded-register-offsets.patch new file mode 100644 index 00000000000..84cfdcdc885 --- /dev/null +++ b/queue-6.3/edac-qcom-get-rid-of-hardcoded-register-offsets.patch @@ -0,0 +1,328 @@ +From 85fb92316e8d21ec51d06aba2e02bb788bb053ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 17:16:35 +0530 +Subject: EDAC/qcom: Get rid of hardcoded register offsets + +From: Manivannan Sadhasivam + +[ Upstream commit cbd77119b6355872cd308a60e99f9ca678435d15 ] + +The LLCC EDAC register offsets varies between each SoC. Hardcoding the +register offsets won't work and will often result in crash due to +accessing the wrong locations. + +Hence, get the register offsets from the LLCC driver matching the +individual SoCs. + +Cc: # 6.0: 5365cea199c7 ("soc: qcom: llcc: Rename reg_offset structs to reflect LLCC version") +Cc: # 6.0: c13d7d261e36 ("soc: qcom: llcc: Pass LLCC version based register offsets to EDAC driver") +Cc: # 6.0 +Fixes: a6e9d7ef252c ("soc: qcom: llcc: Add configuration data for SM8450 SoC") +Acked-by: Borislav Petkov (AMD) +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230517114635.76358-3-manivannan.sadhasivam@linaro.org +Signed-off-by: Sasha Levin +--- + drivers/edac/qcom_edac.c | 116 ++++++++++++++--------------- + include/linux/soc/qcom/llcc-qcom.h | 6 -- + 2 files changed, 58 insertions(+), 64 deletions(-) + +diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c +index 265e0fb39bc7d..ae84558481770 100644 +--- a/drivers/edac/qcom_edac.c ++++ b/drivers/edac/qcom_edac.c +@@ -21,30 +21,9 @@ + #define TRP_SYN_REG_CNT 6 + #define DRP_SYN_REG_CNT 8 + +-#define LLCC_COMMON_STATUS0 0x0003000c + #define LLCC_LB_CNT_MASK GENMASK(31, 28) + #define LLCC_LB_CNT_SHIFT 28 + +-/* Single & double bit syndrome register offsets */ +-#define TRP_ECC_SB_ERR_SYN0 0x0002304c +-#define TRP_ECC_DB_ERR_SYN0 0x00020370 +-#define DRP_ECC_SB_ERR_SYN0 0x0004204c +-#define DRP_ECC_DB_ERR_SYN0 0x00042070 +- +-/* Error register offsets */ +-#define TRP_ECC_ERROR_STATUS1 0x00020348 +-#define TRP_ECC_ERROR_STATUS0 0x00020344 +-#define DRP_ECC_ERROR_STATUS1 0x00042048 +-#define DRP_ECC_ERROR_STATUS0 0x00042044 +- +-/* TRP, DRP interrupt register offsets */ +-#define DRP_INTERRUPT_STATUS 0x00041000 +-#define TRP_INTERRUPT_0_STATUS 0x00020480 +-#define DRP_INTERRUPT_CLEAR 0x00041008 +-#define DRP_ECC_ERROR_CNTR_CLEAR 0x00040004 +-#define TRP_INTERRUPT_0_CLEAR 0x00020484 +-#define TRP_ECC_ERROR_CNTR_CLEAR 0x00020440 +- + /* Mask and shift macros */ + #define ECC_DB_ERR_COUNT_MASK GENMASK(4, 0) + #define ECC_DB_ERR_WAYS_MASK GENMASK(31, 16) +@@ -60,15 +39,6 @@ + #define DRP_TRP_INT_CLEAR GENMASK(1, 0) + #define DRP_TRP_CNT_CLEAR GENMASK(1, 0) + +-/* Config registers offsets*/ +-#define DRP_ECC_ERROR_CFG 0x00040000 +- +-/* Tag RAM, Data RAM interrupt register offsets */ +-#define CMN_INTERRUPT_0_ENABLE 0x0003001c +-#define CMN_INTERRUPT_2_ENABLE 0x0003003c +-#define TRP_INTERRUPT_0_ENABLE 0x00020488 +-#define DRP_INTERRUPT_ENABLE 0x0004100c +- + #define SB_ERROR_THRESHOLD 0x1 + #define SB_ERROR_THRESHOLD_SHIFT 24 + #define SB_DB_TRP_INTERRUPT_ENABLE 0x3 +@@ -88,9 +58,6 @@ enum { + static const struct llcc_edac_reg_data edac_reg_data[] = { + [LLCC_DRAM_CE] = { + .name = "DRAM Single-bit", +- .synd_reg = DRP_ECC_SB_ERR_SYN0, +- .count_status_reg = DRP_ECC_ERROR_STATUS1, +- .ways_status_reg = DRP_ECC_ERROR_STATUS0, + .reg_cnt = DRP_SYN_REG_CNT, + .count_mask = ECC_SB_ERR_COUNT_MASK, + .ways_mask = ECC_SB_ERR_WAYS_MASK, +@@ -98,9 +65,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = { + }, + [LLCC_DRAM_UE] = { + .name = "DRAM Double-bit", +- .synd_reg = DRP_ECC_DB_ERR_SYN0, +- .count_status_reg = DRP_ECC_ERROR_STATUS1, +- .ways_status_reg = DRP_ECC_ERROR_STATUS0, + .reg_cnt = DRP_SYN_REG_CNT, + .count_mask = ECC_DB_ERR_COUNT_MASK, + .ways_mask = ECC_DB_ERR_WAYS_MASK, +@@ -108,9 +72,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = { + }, + [LLCC_TRAM_CE] = { + .name = "TRAM Single-bit", +- .synd_reg = TRP_ECC_SB_ERR_SYN0, +- .count_status_reg = TRP_ECC_ERROR_STATUS1, +- .ways_status_reg = TRP_ECC_ERROR_STATUS0, + .reg_cnt = TRP_SYN_REG_CNT, + .count_mask = ECC_SB_ERR_COUNT_MASK, + .ways_mask = ECC_SB_ERR_WAYS_MASK, +@@ -118,9 +79,6 @@ static const struct llcc_edac_reg_data edac_reg_data[] = { + }, + [LLCC_TRAM_UE] = { + .name = "TRAM Double-bit", +- .synd_reg = TRP_ECC_DB_ERR_SYN0, +- .count_status_reg = TRP_ECC_ERROR_STATUS1, +- .ways_status_reg = TRP_ECC_ERROR_STATUS0, + .reg_cnt = TRP_SYN_REG_CNT, + .count_mask = ECC_DB_ERR_COUNT_MASK, + .ways_mask = ECC_DB_ERR_WAYS_MASK, +@@ -128,7 +86,7 @@ static const struct llcc_edac_reg_data edac_reg_data[] = { + }, + }; + +-static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap) ++static int qcom_llcc_core_setup(struct llcc_drv_data *drv, struct regmap *llcc_bcast_regmap) + { + u32 sb_err_threshold; + int ret; +@@ -137,31 +95,31 @@ static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap) + * Configure interrupt enable registers such that Tag, Data RAM related + * interrupts are propagated to interrupt controller for servicing + */ +- ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE, ++ ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, + TRP0_INTERRUPT_ENABLE, + TRP0_INTERRUPT_ENABLE); + if (ret) + return ret; + +- ret = regmap_update_bits(llcc_bcast_regmap, TRP_INTERRUPT_0_ENABLE, ++ ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->trp_interrupt_0_enable, + SB_DB_TRP_INTERRUPT_ENABLE, + SB_DB_TRP_INTERRUPT_ENABLE); + if (ret) + return ret; + + sb_err_threshold = (SB_ERROR_THRESHOLD << SB_ERROR_THRESHOLD_SHIFT); +- ret = regmap_write(llcc_bcast_regmap, DRP_ECC_ERROR_CFG, ++ ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_ecc_error_cfg, + sb_err_threshold); + if (ret) + return ret; + +- ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE, ++ ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable, + DRP0_INTERRUPT_ENABLE, + DRP0_INTERRUPT_ENABLE); + if (ret) + return ret; + +- ret = regmap_write(llcc_bcast_regmap, DRP_INTERRUPT_ENABLE, ++ ret = regmap_write(llcc_bcast_regmap, drv->edac_reg_offset->drp_interrupt_enable, + SB_DB_DRP_INTERRUPT_ENABLE); + return ret; + } +@@ -175,24 +133,28 @@ qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv) + switch (err_type) { + case LLCC_DRAM_CE: + case LLCC_DRAM_UE: +- ret = regmap_write(drv->bcast_regmap, DRP_INTERRUPT_CLEAR, ++ ret = regmap_write(drv->bcast_regmap, ++ drv->edac_reg_offset->drp_interrupt_clear, + DRP_TRP_INT_CLEAR); + if (ret) + return ret; + +- ret = regmap_write(drv->bcast_regmap, DRP_ECC_ERROR_CNTR_CLEAR, ++ ret = regmap_write(drv->bcast_regmap, ++ drv->edac_reg_offset->drp_ecc_error_cntr_clear, + DRP_TRP_CNT_CLEAR); + if (ret) + return ret; + break; + case LLCC_TRAM_CE: + case LLCC_TRAM_UE: +- ret = regmap_write(drv->bcast_regmap, TRP_INTERRUPT_0_CLEAR, ++ ret = regmap_write(drv->bcast_regmap, ++ drv->edac_reg_offset->trp_interrupt_0_clear, + DRP_TRP_INT_CLEAR); + if (ret) + return ret; + +- ret = regmap_write(drv->bcast_regmap, TRP_ECC_ERROR_CNTR_CLEAR, ++ ret = regmap_write(drv->bcast_regmap, ++ drv->edac_reg_offset->trp_ecc_error_cntr_clear, + DRP_TRP_CNT_CLEAR); + if (ret) + return ret; +@@ -205,16 +167,54 @@ qcom_llcc_clear_error_status(int err_type, struct llcc_drv_data *drv) + return ret; + } + ++struct qcom_llcc_syn_regs { ++ u32 synd_reg; ++ u32 count_status_reg; ++ u32 ways_status_reg; ++}; ++ ++static void get_reg_offsets(struct llcc_drv_data *drv, int err_type, ++ struct qcom_llcc_syn_regs *syn_regs) ++{ ++ const struct llcc_edac_reg_offset *edac_reg_offset = drv->edac_reg_offset; ++ ++ switch (err_type) { ++ case LLCC_DRAM_CE: ++ syn_regs->synd_reg = edac_reg_offset->drp_ecc_sb_err_syn0; ++ syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1; ++ syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0; ++ break; ++ case LLCC_DRAM_UE: ++ syn_regs->synd_reg = edac_reg_offset->drp_ecc_db_err_syn0; ++ syn_regs->count_status_reg = edac_reg_offset->drp_ecc_error_status1; ++ syn_regs->ways_status_reg = edac_reg_offset->drp_ecc_error_status0; ++ break; ++ case LLCC_TRAM_CE: ++ syn_regs->synd_reg = edac_reg_offset->trp_ecc_sb_err_syn0; ++ syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1; ++ syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0; ++ break; ++ case LLCC_TRAM_UE: ++ syn_regs->synd_reg = edac_reg_offset->trp_ecc_db_err_syn0; ++ syn_regs->count_status_reg = edac_reg_offset->trp_ecc_error_status1; ++ syn_regs->ways_status_reg = edac_reg_offset->trp_ecc_error_status0; ++ break; ++ } ++} ++ + /* Dump Syndrome registers data for Tag RAM, Data RAM bit errors*/ + static int + dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + { + struct llcc_edac_reg_data reg_data = edac_reg_data[err_type]; ++ struct qcom_llcc_syn_regs regs = { }; + int err_cnt, err_ways, ret, i; + u32 synd_reg, synd_val; + ++ get_reg_offsets(drv, err_type, ®s); ++ + for (i = 0; i < reg_data.reg_cnt; i++) { +- synd_reg = reg_data.synd_reg + (i * 4); ++ synd_reg = regs.synd_reg + (i * 4); + ret = regmap_read(drv->regmaps[bank], synd_reg, + &synd_val); + if (ret) +@@ -224,7 +224,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + reg_data.name, i, synd_val); + } + +- ret = regmap_read(drv->regmaps[bank], reg_data.count_status_reg, ++ ret = regmap_read(drv->regmaps[bank], regs.count_status_reg, + &err_cnt); + if (ret) + goto clear; +@@ -234,7 +234,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n", + reg_data.name, err_cnt); + +- ret = regmap_read(drv->regmaps[bank], reg_data.ways_status_reg, ++ ret = regmap_read(drv->regmaps[bank], regs.ways_status_reg, + &err_ways); + if (ret) + goto clear; +@@ -295,7 +295,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl) + + /* Iterate over the banks and look for Tag RAM or Data RAM errors */ + for (i = 0; i < drv->num_banks; i++) { +- ret = regmap_read(drv->regmaps[i], DRP_INTERRUPT_STATUS, ++ ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->drp_interrupt_status, + &drp_error); + + if (!ret && (drp_error & SB_ECC_ERROR)) { +@@ -310,7 +310,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl) + if (!ret) + irq_rc = IRQ_HANDLED; + +- ret = regmap_read(drv->regmaps[i], TRP_INTERRUPT_0_STATUS, ++ ret = regmap_read(drv->regmaps[i], drv->edac_reg_offset->trp_interrupt_0_status, + &trp_error); + + if (!ret && (trp_error & SB_ECC_ERROR)) { +@@ -342,7 +342,7 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev) + int ecc_irq; + int rc; + +- rc = qcom_llcc_core_setup(llcc_driv_data->bcast_regmap); ++ rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap); + if (rc) + return rc; + +diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h +index 423220e660262..93417ba1ead4a 100644 +--- a/include/linux/soc/qcom/llcc-qcom.h ++++ b/include/linux/soc/qcom/llcc-qcom.h +@@ -69,9 +69,6 @@ struct llcc_slice_desc { + /** + * struct llcc_edac_reg_data - llcc edac registers data for each error type + * @name: Name of the error +- * @synd_reg: Syndrome register address +- * @count_status_reg: Status register address to read the error count +- * @ways_status_reg: Status register address to read the error ways + * @reg_cnt: Number of registers + * @count_mask: Mask value to get the error count + * @ways_mask: Mask value to get the error ways +@@ -80,9 +77,6 @@ struct llcc_slice_desc { + */ + struct llcc_edac_reg_data { + char *name; +- u64 synd_reg; +- u64 count_status_reg; +- u64 ways_status_reg; + u32 reg_cnt; + u32 count_mask; + u32 ways_mask; +-- +2.39.2 + diff --git a/queue-6.3/ksmbd-validate-smb-request-protocol-id.patch b/queue-6.3/ksmbd-validate-smb-request-protocol-id.patch new file mode 100644 index 00000000000..689aa01f9a4 --- /dev/null +++ b/queue-6.3/ksmbd-validate-smb-request-protocol-id.patch @@ -0,0 +1,88 @@ +From 40e2f50959b90719fb5d4d735e6fafe7557213e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 May 2023 17:59:32 +0900 +Subject: ksmbd: validate smb request protocol id + +From: Namjae Jeon + +[ Upstream commit 1c1bcf2d3ea061613119b534f57507c377df20f9 ] + +This patch add the validation for smb request protocol id. +If it is not one of the four ids(SMB1_PROTO_NUMBER, SMB2_PROTO_NUMBER, +SMB2_TRANSFORM_PROTO_NUM, SMB2_COMPRESSION_TRANSFORM_ID), don't allow +processing the request. And this will fix the following KASAN warning +also. + +[ 13.905265] BUG: KASAN: slab-out-of-bounds in init_smb2_rsp_hdr+0x1b9/0x1f0 +[ 13.905900] Read of size 16 at addr ffff888005fd2f34 by task kworker/0:2/44 +... +[ 13.908553] Call Trace: +[ 13.908793] +[ 13.908995] dump_stack_lvl+0x33/0x50 +[ 13.909369] print_report+0xcc/0x620 +[ 13.910870] kasan_report+0xae/0xe0 +[ 13.911519] kasan_check_range+0x35/0x1b0 +[ 13.911796] init_smb2_rsp_hdr+0x1b9/0x1f0 +[ 13.912492] handle_ksmbd_work+0xe5/0x820 + +Cc: stable@vger.kernel.org +Reported-by: Chih-Yen Chang +Signed-off-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/ksmbd/connection.c | 5 +++-- + fs/ksmbd/smb_common.c | 14 +++++++++++++- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c +index e11d4a1e63d73..2a717d158f02e 100644 +--- a/fs/ksmbd/connection.c ++++ b/fs/ksmbd/connection.c +@@ -364,8 +364,6 @@ int ksmbd_conn_handler_loop(void *p) + break; + + memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf)); +- if (!ksmbd_smb_request(conn)) +- break; + + /* + * We already read 4 bytes to find out PDU size, now +@@ -383,6 +381,9 @@ int ksmbd_conn_handler_loop(void *p) + continue; + } + ++ if (!ksmbd_smb_request(conn)) ++ break; ++ + if (((struct smb2_hdr *)smb2_get_msg(conn->request_buf))->ProtocolId == + SMB2_PROTO_NUMBER) { + if (pdu_size < SMB2_MIN_SUPPORTED_HEADER_SIZE) +diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c +index af0c2a9b85290..569e5eecdf3db 100644 +--- a/fs/ksmbd/smb_common.c ++++ b/fs/ksmbd/smb_common.c +@@ -158,7 +158,19 @@ int ksmbd_verify_smb_message(struct ksmbd_work *work) + */ + bool ksmbd_smb_request(struct ksmbd_conn *conn) + { +- return conn->request_buf[0] == 0; ++ __le32 *proto = (__le32 *)smb2_get_msg(conn->request_buf); ++ ++ if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) { ++ pr_err_ratelimited("smb2 compression not support yet"); ++ return false; ++ } ++ ++ if (*proto != SMB1_PROTO_NUMBER && ++ *proto != SMB2_PROTO_NUMBER && ++ *proto != SMB2_TRANSFORM_PROTO_NUM) ++ return false; ++ ++ return true; + } + + static bool supported_protocol(int idx) +-- +2.39.2 + diff --git a/queue-6.3/qcom-llcc-edac-fix-the-base-address-used-for-accessi.patch b/queue-6.3/qcom-llcc-edac-fix-the-base-address-used-for-accessi.patch new file mode 100644 index 00000000000..c38bfc4b5a4 --- /dev/null +++ b/queue-6.3/qcom-llcc-edac-fix-the-base-address-used-for-accessi.patch @@ -0,0 +1,268 @@ +From 09f909d673e97fbd5f75085528632d0f72bf0710 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Mar 2023 13:34:41 +0530 +Subject: qcom: llcc/edac: Fix the base address used for accessing LLCC banks + +From: Manivannan Sadhasivam + +[ Upstream commit ee13b5008707948d3052c1b5aab485c6cd53658e ] + +The Qualcomm LLCC/EDAC drivers were using a fixed register stride for +accessing the (Control and Status Registers) CSRs of each LLCC bank. +This stride only works for some SoCs like SDM845 for which driver +support was initially added. + +But the later SoCs use different register stride that vary between the +banks with holes in-between. So it is not possible to use a single register +stride for accessing the CSRs of each bank. By doing so could result in a +crash. + +For fixing this issue, let's obtain the base address of each LLCC bank from +devicetree and get rid of the fixed stride. This also means, there is no +need to rely on reg-names property and the base addresses can be obtained +using the index. + +First index is LLCC bank 0 and last index is LLCC broadcast. If the SoC +supports more than one bank, then those need to be defined in devicetree +for index from 1..N-1. + +Reported-by: Parikshit Pareek +Tested-by: Luca Weiss +Tested-by: Steev Klimaszewski # Thinkpad X13s +Tested-by: Andrew Halaney # sa8540p-ride +Reviewed-by: Borislav Petkov (AMD) +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20230314080443.64635-13-manivannan.sadhasivam@linaro.org +Stable-dep-of: cbd77119b635 ("EDAC/qcom: Get rid of hardcoded register offsets") +Signed-off-by: Sasha Levin +--- + drivers/edac/qcom_edac.c | 14 +++--- + drivers/soc/qcom/llcc-qcom.c | 72 +++++++++++++++++------------- + include/linux/soc/qcom/llcc-qcom.h | 6 +-- + 3 files changed, 48 insertions(+), 44 deletions(-) + +diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c +index a7158b570ddd0..265e0fb39bc7d 100644 +--- a/drivers/edac/qcom_edac.c ++++ b/drivers/edac/qcom_edac.c +@@ -215,7 +215,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + + for (i = 0; i < reg_data.reg_cnt; i++) { + synd_reg = reg_data.synd_reg + (i * 4); +- ret = regmap_read(drv->regmap, drv->offsets[bank] + synd_reg, ++ ret = regmap_read(drv->regmaps[bank], synd_reg, + &synd_val); + if (ret) + goto clear; +@@ -224,8 +224,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + reg_data.name, i, synd_val); + } + +- ret = regmap_read(drv->regmap, +- drv->offsets[bank] + reg_data.count_status_reg, ++ ret = regmap_read(drv->regmaps[bank], reg_data.count_status_reg, + &err_cnt); + if (ret) + goto clear; +@@ -235,8 +234,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) + edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n", + reg_data.name, err_cnt); + +- ret = regmap_read(drv->regmap, +- drv->offsets[bank] + reg_data.ways_status_reg, ++ ret = regmap_read(drv->regmaps[bank], reg_data.ways_status_reg, + &err_ways); + if (ret) + goto clear; +@@ -297,8 +295,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl) + + /* Iterate over the banks and look for Tag RAM or Data RAM errors */ + for (i = 0; i < drv->num_banks; i++) { +- ret = regmap_read(drv->regmap, +- drv->offsets[i] + DRP_INTERRUPT_STATUS, ++ ret = regmap_read(drv->regmaps[i], DRP_INTERRUPT_STATUS, + &drp_error); + + if (!ret && (drp_error & SB_ECC_ERROR)) { +@@ -313,8 +310,7 @@ static irqreturn_t llcc_ecc_irq_handler(int irq, void *edev_ctl) + if (!ret) + irq_rc = IRQ_HANDLED; + +- ret = regmap_read(drv->regmap, +- drv->offsets[i] + TRP_INTERRUPT_0_STATUS, ++ ret = regmap_read(drv->regmaps[i], TRP_INTERRUPT_0_STATUS, + &trp_error); + + if (!ret && (trp_error & SB_ECC_ERROR)) { +diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c +index d4d3eced52f35..8298decc518e3 100644 +--- a/drivers/soc/qcom/llcc-qcom.c ++++ b/drivers/soc/qcom/llcc-qcom.c +@@ -62,8 +62,6 @@ + #define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c + #define LLCC_TRP_ALGO_CFG8 0x21f30 + +-#define BANK_OFFSET_STRIDE 0x80000 +- + #define LLCC_VERSION_2_0_0_0 0x02000000 + #define LLCC_VERSION_2_1_0_0 0x02010000 + #define LLCC_VERSION_4_1_0_0 0x04010000 +@@ -900,8 +898,8 @@ static int qcom_llcc_remove(struct platform_device *pdev) + return 0; + } + +-static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, +- const char *name) ++static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index, ++ const char *name) + { + void __iomem *base; + struct regmap_config llcc_regmap_config = { +@@ -911,7 +909,7 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, + .fast_io = true, + }; + +- base = devm_platform_ioremap_resource_byname(pdev, name); ++ base = devm_platform_ioremap_resource(pdev, index); + if (IS_ERR(base)) + return ERR_CAST(base); + +@@ -929,6 +927,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) + const struct llcc_slice_config *llcc_cfg; + u32 sz; + u32 version; ++ struct regmap *regmap; + + drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); + if (!drv_data) { +@@ -936,21 +935,51 @@ static int qcom_llcc_probe(struct platform_device *pdev) + goto err; + } + +- drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base"); +- if (IS_ERR(drv_data->regmap)) { +- ret = PTR_ERR(drv_data->regmap); ++ /* Initialize the first LLCC bank regmap */ ++ regmap = qcom_llcc_init_mmio(pdev, 0, "llcc0_base"); ++ if (IS_ERR(regmap)) { ++ ret = PTR_ERR(regmap); + goto err; + } + +- drv_data->bcast_regmap = +- qcom_llcc_init_mmio(pdev, "llcc_broadcast_base"); ++ cfg = of_device_get_match_data(&pdev->dev); ++ ++ ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks); ++ if (ret) ++ goto err; ++ ++ num_banks &= LLCC_LB_CNT_MASK; ++ num_banks >>= LLCC_LB_CNT_SHIFT; ++ drv_data->num_banks = num_banks; ++ ++ drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL); ++ if (!drv_data->regmaps) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ drv_data->regmaps[0] = regmap; ++ ++ /* Initialize rest of LLCC bank regmaps */ ++ for (i = 1; i < num_banks; i++) { ++ char *base = kasprintf(GFP_KERNEL, "llcc%d_base", i); ++ ++ drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base); ++ if (IS_ERR(drv_data->regmaps[i])) { ++ ret = PTR_ERR(drv_data->regmaps[i]); ++ kfree(base); ++ goto err; ++ } ++ ++ kfree(base); ++ } ++ ++ drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base"); + if (IS_ERR(drv_data->bcast_regmap)) { + ret = PTR_ERR(drv_data->bcast_regmap); + goto err; + } + +- cfg = of_device_get_match_data(&pdev->dev); +- + /* Extract version of the IP */ + ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO], + &version); +@@ -959,15 +988,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) + + drv_data->version = version; + +- ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], +- &num_banks); +- if (ret) +- goto err; +- +- num_banks &= LLCC_LB_CNT_MASK; +- num_banks >>= LLCC_LB_CNT_SHIFT; +- drv_data->num_banks = num_banks; +- + llcc_cfg = cfg->sct_data; + sz = cfg->size; + +@@ -975,16 +995,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) + if (llcc_cfg[i].slice_id > drv_data->max_slices) + drv_data->max_slices = llcc_cfg[i].slice_id; + +- drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32), +- GFP_KERNEL); +- if (!drv_data->offsets) { +- ret = -ENOMEM; +- goto err; +- } +- +- for (i = 0; i < num_banks; i++) +- drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; +- + drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices, + GFP_KERNEL); + if (!drv_data->bitmap) { +diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h +index ad1fd718169d9..423220e660262 100644 +--- a/include/linux/soc/qcom/llcc-qcom.h ++++ b/include/linux/soc/qcom/llcc-qcom.h +@@ -120,7 +120,7 @@ struct llcc_edac_reg_offset { + + /** + * struct llcc_drv_data - Data associated with the llcc driver +- * @regmap: regmap associated with the llcc device ++ * @regmaps: regmaps associated with the llcc device + * @bcast_regmap: regmap associated with llcc broadcast offset + * @cfg: pointer to the data structure for slice configuration + * @edac_reg_offset: Offset of the LLCC EDAC registers +@@ -129,12 +129,11 @@ struct llcc_edac_reg_offset { + * @max_slices: max slices as read from device tree + * @num_banks: Number of llcc banks + * @bitmap: Bit map to track the active slice ids +- * @offsets: Pointer to the bank offsets array + * @ecc_irq: interrupt for llcc cache error detection and reporting + * @version: Indicates the LLCC version + */ + struct llcc_drv_data { +- struct regmap *regmap; ++ struct regmap **regmaps; + struct regmap *bcast_regmap; + const struct llcc_slice_config *cfg; + const struct llcc_edac_reg_offset *edac_reg_offset; +@@ -143,7 +142,6 @@ struct llcc_drv_data { + u32 max_slices; + u32 num_banks; + unsigned long *bitmap; +- u32 *offsets; + int ecc_irq; + u32 version; + }; +-- +2.39.2 + diff --git a/queue-6.3/series b/queue-6.3/series new file mode 100644 index 00000000000..e52434bf660 --- /dev/null +++ b/queue-6.3/series @@ -0,0 +1,7 @@ +x86-head-64-switch-to-kernel_cs-as-soon-as-new-gdt-i.patch +cgroup-bpf-use-cgroup_lock-cgroup_unlock-wrappers.patch +cgroup-always-put-cset-in-cgroup_css_set_put_fork.patch +cgroup-fix-missing-cpus_read_-lock-unlock-in-cgroup_.patch +qcom-llcc-edac-fix-the-base-address-used-for-accessi.patch +edac-qcom-get-rid-of-hardcoded-register-offsets.patch +ksmbd-validate-smb-request-protocol-id.patch diff --git a/queue-6.3/x86-head-64-switch-to-kernel_cs-as-soon-as-new-gdt-i.patch b/queue-6.3/x86-head-64-switch-to-kernel_cs-as-soon-as-new-gdt-i.patch new file mode 100644 index 00000000000..3070640fd2a --- /dev/null +++ b/queue-6.3/x86-head-64-switch-to-kernel_cs-as-soon-as-new-gdt-i.patch @@ -0,0 +1,80 @@ +From ffb77ed1a474a5a2f62efce42685ba4a3c61055b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 May 2023 11:26:41 -0500 +Subject: x86/head/64: Switch to KERNEL_CS as soon as new GDT is installed + +From: Tom Lendacky + +[ Upstream commit a37f2699c36a7f6606ba3300f243227856c5ad6b ] + +The call to startup_64_setup_env() will install a new GDT but does not +actually switch to using the KERNEL_CS entry until returning from the +function call. + +Commit bcce82908333 ("x86/sev: Detect/setup SEV/SME features earlier in +boot") moved the call to sme_enable() earlier in the boot process and in +between the call to startup_64_setup_env() and the switch to KERNEL_CS. +An SEV-ES or an SEV-SNP guest will trigger #VC exceptions during the call +to sme_enable() and if the CS pushed on the stack as part of the exception +and used by IRETQ is not mapped by the new GDT, then problems occur. +Today, the current CS when entering startup_64 is the kernel CS value +because it was set up by the decompressor code, so no issue is seen. + +However, a recent patchset that looked to avoid using the legacy +decompressor during an EFI boot exposed this bug. At entry to startup_64, +the CS value is that of EFI and is not mapped in the new kernel GDT. So +when a #VC exception occurs, the CS value used by IRETQ is not valid and +the guest boot crashes. + +Fix this issue by moving the block that switches to the KERNEL_CS value to +be done immediately after returning from startup_64_setup_env(). + +Fixes: bcce82908333 ("x86/sev: Detect/setup SEV/SME features earlier in boot") +Signed-off-by: Tom Lendacky +Signed-off-by: Dave Hansen +Reviewed-by: Joerg Roedel +Link: https://lore.kernel.org/all/6ff1f28af2829cc9aea357ebee285825f90a431f.1684340801.git.thomas.lendacky%40amd.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/head_64.S | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S +index 222efd4a09bc8..f047723c6ca5d 100644 +--- a/arch/x86/kernel/head_64.S ++++ b/arch/x86/kernel/head_64.S +@@ -85,6 +85,15 @@ SYM_CODE_START_NOALIGN(startup_64) + call startup_64_setup_env + popq %rsi + ++ /* Now switch to __KERNEL_CS so IRET works reliably */ ++ pushq $__KERNEL_CS ++ leaq .Lon_kernel_cs(%rip), %rax ++ pushq %rax ++ lretq ++ ++.Lon_kernel_cs: ++ UNWIND_HINT_EMPTY ++ + #ifdef CONFIG_AMD_MEM_ENCRYPT + /* + * Activate SEV/SME memory encryption if supported/enabled. This needs to +@@ -98,15 +107,6 @@ SYM_CODE_START_NOALIGN(startup_64) + popq %rsi + #endif + +- /* Now switch to __KERNEL_CS so IRET works reliably */ +- pushq $__KERNEL_CS +- leaq .Lon_kernel_cs(%rip), %rax +- pushq %rax +- lretq +- +-.Lon_kernel_cs: +- UNWIND_HINT_EMPTY +- + /* Sanitize CPU configuration */ + call verify_cpu + +-- +2.39.2 + -- 2.47.2