hulk inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8424 ---------------------------------------- When the XCU subsystem is not enabled, the root node of the XCU subsystem defaults to struct freezer, and the members linked list of xsched_group remains uninitialized. Attempting to add nodes to this uninitialized list triggers a kernel list corruption error: [ 3376.708041] list_add corruption. prev is NULL. [ 3376.708372] Call trace: [ 3376.708375] __list_add_valid_or_report+0x58/0xe8 [ 3376.708378] xsched_group_xse_attach+0x68/0xe8 [ 3376.708393] xsched_group_inherit+0x38/0x170 [ 3376.708397] init_xsched_entity+0x50/0x1a0 [ 3376.708400] alloc_ctx_from_vstream+0x10c/0x1c0 [ 3376.708403] vstream_bind_to_ctx+0x16c/0x1a8 [ 3376.708406] sqcq_alloc+0x12c/0x380 [ 3376.708409] vstream_alloc+0x20/0x48 [ 3376.708412] __se_sys_vstream_manage+0xa0/0x1e8 [ 3376.708414] __arm64_sys_vstream_manage+0x1c/0x30 [ 3376.708417] invoke_syscall+0x50/0x128 [ 3376.708422] el0_svc_common.constprop.0+0xc8/0xf0 [ 3376.708424] do_el0_svc+0x48/0x78 [ 3376.708426] el0_slow_syscall+0x44/0x1e8 [ 3376.708433] el0t_64_sync_handler+0xc0/0xc8 [ 3376.708435] el0t_64_sync+0x188/0x190 [ 3376.708439] ---[ end trace 0000000000000000 ]--- This error occurs because the code attempts to perform list operations on an uninitialized list head, violating kernel list integrity checks. To resolve this, add a check for xcu_cgroup_enabled() at the start of init_xsched_entity. If the XCU subsystem is disabled, return -EPERM immediately to block xsched_entity initialization, avoiding invalid list operations and ensuring system stability. Fixes: 0ca67081a163 ("xSched/cgroup: reuse SUBSYS for xcu and freezer to preserve KABI") Signed-off-by: Liu Kai <liukai284@huawei.com> --- include/linux/xsched.h | 2 ++ kernel/xsched/cgroup.c | 2 +- kernel/xsched/core.c | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/xsched.h b/include/linux/xsched.h index ff314f88169f..e9c580149d55 100644 --- a/include/linux/xsched.h +++ b/include/linux/xsched.h @@ -485,6 +485,8 @@ void xsched_quota_account(struct xsched_group *xg, s64 exec_time); void xsched_quota_check(struct xsched_group *xg, struct xsched_cu *xcu); void xsched_quota_refill(struct work_struct *work); +bool xcu_cgroup_enabled(void); + #define XCU_PERIOD_MIN_MS 1 #define XCU_QUOTA_RUNTIME_INF -1 #define XCU_SHARES_MIN 1 diff --git a/kernel/xsched/cgroup.c b/kernel/xsched/cgroup.c index d22ffc543d45..8d22aa78ea81 100644 --- a/kernel/xsched/cgroup.c +++ b/kernel/xsched/cgroup.c @@ -67,7 +67,7 @@ static int __init xcu_setup(char *str) } __setup("xcu=", xcu_setup); -static bool xcu_cgroup_enabled(void) +bool xcu_cgroup_enabled(void) { return static_branch_unlikely(&xcu_cgroup_key); } diff --git a/kernel/xsched/core.c b/kernel/xsched/core.c index 1d835fc44d0c..5e3e4e02dfac 100644 --- a/kernel/xsched/core.c +++ b/kernel/xsched/core.c @@ -463,6 +463,9 @@ int init_xsched_entity(struct xsched_context *ctx, struct vstream_info *vs) xse = &ctx->xse; #ifdef CONFIG_CGROUP_XCU + if (!xcu_cgroup_enabled()) + return -EPERM; + xsched_group_inherit(current, xse); /* inherit the scheduler class from the parent group */ class_id = xse->parent_grp->sched_class; -- 2.34.1