2017-11-27 14:22:52

by Chunyu Hu

[permalink] [raw]
Subject: [PATCH] x86/idt: load idt early in start_secondary

For ap, idt is first loaded in cpu_init() with load_current_idt(),
that is to say, no exception can be handled before there. And then
the idt_table has been completed by the bp.

While there are some WARNs which needs the UD exception handling
in the early boot code might be triggered when something uexpected
happens during boot. In that case, cpu would fail to boot as the
exception can't be handled. A WARNing during boot is not usually
meaning the system could not boot.

One use case is when ftrace=function is setup in kernel cmdline, the
ftrace callback function will be called for every traced function.
And in my case, the first traced function is load_ucode_ap. And there
are WARN()s in function trace callback handling, it failed to reboot
as one of the WARN()s is triggered before load_current_idt() executed.

To make WARN()s can work earlier to ap, we load the idt_table early
in start_secondary, and keep the second time idt load in cpu_init,
as there is a load_ucode_ap() there.

Signed-off-by: Chunyu Hu <[email protected]>
---
arch/x86/kernel/smpboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3d01df7..05a97d5 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -237,7 +237,7 @@ static void notrace start_secondary(void *unused)
load_cr3(swapper_pg_dir);
__flush_tlb_all();
#endif
-
+ load_current_idt();
cpu_init();
x86_cpuinit.early_percpu_clock_init();
preempt_disable();
--
1.8.3.1


From 1585311772355695264@xxx Tue Nov 28 12:12:00 +0000 2017
X-GM-THRID: 1585305005485339652
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread


Subject: [tip:x86/urgent] x86/idt: Load idt early in start_secondary

Commit-ID: 55d2d0ad2fb4325f615d1950486fbc5e6fba1769
Gitweb: https://git.kernel.org/tip/55d2d0ad2fb4325f615d1950486fbc5e6fba1769
Author: Chunyu Hu <[email protected]>
AuthorDate: Mon, 27 Nov 2017 22:21:39 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 28 Nov 2017 08:15:40 +0100

x86/idt: Load idt early in start_secondary

On a secondary, idt is first loaded in cpu_init() with load_current_idt(),
i.e. no exceptions can be handled before that point.

The conversion of WARN() to use UD requires the IDT being loaded earlier as
any warning between start_secondary() and load_curren_idt() in cpu_init()
will result in an unhandled @UD exception and therefore fail the bringup of
the CPU.

Install the IDT handlers right in start_secondary() before calling cpu_init().

[ tglx: Massaged changelog ]

Fixes: 9a93848fe787 ("x86/debug: Implement __WARN() using UD0")
Signed-off-by: Chunyu Hu <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: https://lkml.kernel.org/r/[email protected]
---
arch/x86/kernel/smpboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3d01df7..05a97d5 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -237,7 +237,7 @@ static void notrace start_secondary(void *unused)
load_cr3(swapper_pg_dir);
__flush_tlb_all();
#endif
-
+ load_current_idt();
cpu_init();
x86_cpuinit.early_percpu_clock_init();
preempt_disable();

From 1585264315113244510@xxx Mon Nov 27 23:37:42 +0000 2017
X-GM-THRID: 1585264315113244510
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread

Subject: [tip:x86/urgent] x86/idt: Load idt early in start_secondary

Commit-ID: d632044a53571267034f430a5433f048ff8168da
Gitweb: https://git.kernel.org/tip/d632044a53571267034f430a5433f048ff8168da
Author: Chunyu Hu <[email protected]>
AuthorDate: Mon, 27 Nov 2017 22:21:39 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 28 Nov 2017 00:28:56 +0100

x86/idt: Load idt early in start_secondary

On a secondary, idt is first loaded in cpu_init() with load_current_idt(),
i.e. no exceptions can be handled before that point.

The conversion of WARN() to use UD requires the IDT being loaded earlier as
any warning between start_secondary() and load_curren_idt() in cpu_init()
will result in an unhandled @UD exception and therefore fail the bringup of
the CPU.

Install the IDT handlers right in start_secondary() before calling cpu_init().

[ tglx: Massaged changelog ]

Signed-off-by: Chunyu Hu <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: https://lkml.kernel.org/r/[email protected]

---
arch/x86/kernel/smpboot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3d01df7..05a97d5 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -237,7 +237,7 @@ static void notrace start_secondary(void *unused)
load_cr3(swapper_pg_dir);
__flush_tlb_all();
#endif
-
+ load_current_idt();
cpu_init();
x86_cpuinit.early_percpu_clock_init();
preempt_disable();

From 1583729029264008975@xxx Sat Nov 11 00:54:59 +0000 2017
X-GM-THRID: 1583067906559816766
X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread