Commit 1509d06c authored by Xiongfeng Wang's avatar Xiongfeng Wang
Browse files

init: only move down lockup_detector_init() when sdei_watchdog is enabled

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8LQCC


CVE: NA

-------------------------------------------------

When I enable CONFIG_DEBUG_PREEMPT and CONFIG_PREEMPT on X86, I got the
following Call Trace:

[    3.341853] BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
[    3.344392] caller is debug_smp_processor_id+0x17/0x20
[    3.344395] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.10.0+ #398
[    3.344397] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.2-0-g5f4c7b1-prebuilt.qemu-project.org 04/01/2014
[    3.344399] Call Trace:
[    3.344410]  dump_stack+0x60/0x76
[    3.344412]  check_preemption_disabled+0xba/0xc0
[    3.344415]  debug_smp_processor_id+0x17/0x20
[    3.344422]  hardlockup_detector_event_create+0xf/0x60
[    3.344427]  hardlockup_detector_perf_init+0xf/0x41
[    3.344430]  watchdog_nmi_probe+0xe/0x10
[    3.344432]  lockup_detector_init+0x22/0x5b
[    3.344437]  kernel_init_freeable+0x20c/0x245
[    3.344439]  ? rest_init+0xd0/0xd0
[    3.344441]  kernel_init+0xe/0x110
[    3.344446]  ret_from_fork+0x22/0x30

It is because sched_init_smp() set 'current->nr_cpus_allowed' to
possible cpu number, and check_preemption_disabled() failed. This issue
is introduced by commit a7905043, which move down
lockup_detector_init() after do_basic_setup(). Fix it by moving
lockup_detector_init() to its origin place when sdei_watchdog is
disabled. There is no problem when sdei_watchdog is enabled because
watchdog_nmi_probe() is overridden in
'arch/arm64/kernel/watchdog_sdei.c' in this case.

Fixes: a7905043 ("lockup_detector: init lockup detector after all the init_calls")
Signed-off-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: default avatarWei Li <liwei391@huawei.com>
Signed-off-by: default avatarChen Jun <chenjun102@huawei.com>
parent cac525db
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@
#define SDEI_NMI_WATCHDOG_HWIRQ		29

static int sdei_watchdog_event_num;
static bool disable_sdei_nmi_watchdog;
bool disable_sdei_nmi_watchdog;
static bool sdei_watchdog_registered;
static DEFINE_PER_CPU(ktime_t, last_check_time);

+2 −0
Original line number Diff line number Diff line
@@ -237,8 +237,10 @@ static inline void nmi_backtrace_stall_check(const struct cpumask *btp) {}

#ifdef CONFIG_SDEI_WATCHDOG
void sdei_watchdog_clear_eoi(void);
extern bool disable_sdei_nmi_watchdog;
#else
static inline void sdei_watchdog_clear_eoi(void) { }
#define disable_sdei_nmi_watchdog 1
#endif

#endif
+5 −1
Original line number Diff line number Diff line
@@ -1539,6 +1539,8 @@ static noinline void __init kernel_init_freeable(void)

	rcu_init_tasks_generic();
	do_pre_smp_initcalls();
	if (disable_sdei_nmi_watchdog)
		lockup_detector_init();

	smp_init();
	sched_init_smp();
@@ -1549,6 +1551,8 @@ static noinline void __init kernel_init_freeable(void)

	do_basic_setup();

	/* sdei_watchdog needs to be initialized after sdei_init */
	if (!disable_sdei_nmi_watchdog)
		lockup_detector_init();

	kunit_run_all_tests();