Skip to content

Commit 85db428

Browse files
finikorgjhedberg
authored andcommitted
arch/x86: Use NMI stack for NMIs
NMI can be triggered at any time, even when in the process of switching stacks. Use special stack for it. Signed-off-by: Andrei Emeltchenko <[email protected]>
1 parent 8db06ae commit 85db428

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

arch/x86/core/intel64/cpu.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ extern uint8_t _exception_stack1[];
2828
extern uint8_t _exception_stack2[];
2929
extern uint8_t _exception_stack3[];
3030

31+
extern uint8_t _nmi_stack[];
32+
extern uint8_t _nmi_stack1[];
33+
extern uint8_t _nmi_stack2[];
34+
extern uint8_t _nmi_stack3[];
35+
3136
#ifdef CONFIG_X86_KPTI
3237
extern uint8_t z_x86_trampoline_stack[];
3338
extern uint8_t z_x86_trampoline_stack1[];
@@ -40,6 +45,7 @@ struct x86_tss64 tss0 = {
4045
#ifdef CONFIG_X86_KPTI
4146
.ist2 = (uint64_t) z_x86_trampoline_stack + Z_X86_TRAMPOLINE_STACK_SIZE,
4247
#endif
48+
.ist6 = (uint64_t) _nmi_stack + CONFIG_X86_EXCEPTION_STACK_SIZE,
4349
.ist7 = (uint64_t) _exception_stack + CONFIG_X86_EXCEPTION_STACK_SIZE,
4450
.iomapb = 0xFFFF,
4551
.cpu = &(_kernel.cpus[0])
@@ -51,6 +57,7 @@ struct x86_tss64 tss1 = {
5157
#ifdef CONFIG_X86_KPTI
5258
.ist2 = (uint64_t) z_x86_trampoline_stack1 + Z_X86_TRAMPOLINE_STACK_SIZE,
5359
#endif
60+
.ist6 = (uint64_t) _nmi_stack1 + CONFIG_X86_EXCEPTION_STACK_SIZE,
5461
.ist7 = (uint64_t) _exception_stack1 + CONFIG_X86_EXCEPTION_STACK_SIZE,
5562
.iomapb = 0xFFFF,
5663
.cpu = &(_kernel.cpus[1])
@@ -63,6 +70,7 @@ struct x86_tss64 tss2 = {
6370
#ifdef CONFIG_X86_KPTI
6471
.ist2 = (uint64_t) z_x86_trampoline_stack2 + Z_X86_TRAMPOLINE_STACK_SIZE,
6572
#endif
73+
.ist6 = (uint64_t) _nmi_stack2 + CONFIG_X86_EXCEPTION_STACK_SIZE,
6674
.ist7 = (uint64_t) _exception_stack2 + CONFIG_X86_EXCEPTION_STACK_SIZE,
6775
.iomapb = 0xFFFF,
6876
.cpu = &(_kernel.cpus[2])
@@ -75,6 +83,7 @@ struct x86_tss64 tss3 = {
7583
#ifdef CONFIG_X86_KPTI
7684
.ist2 = (uint64_t) z_x86_trampoline_stack3 + Z_X86_TRAMPOLINE_STACK_SIZE,
7785
#endif
86+
.ist6 = (uint64_t) _nmi_stack3 + CONFIG_X86_EXCEPTION_STACK_SIZE,
7887
.ist7 = (uint64_t) _exception_stack3 + CONFIG_X86_EXCEPTION_STACK_SIZE,
7988
.iomapb = 0xFFFF,
8089
.cpu = &(_kernel.cpus[3])

arch/x86/core/intel64/locore.S

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,16 +821,18 @@ IRQ(248); IRQ(249); IRQ(250); IRQ(251); IRQ(252); IRQ(253); IRQ(254); IRQ(255)
821821
#define IRQ_STACK 2
822822
#define EXC_STACK 2
823823
#define BAD_STACK 2
824+
#define NMI_STACK 2
824825
#else
825826
#define IRQ_STACK 1
827+
#define NMI_STACK 6 /* NMI stack */
826828
#define EXC_STACK 7
827-
#define BAD_STACK 7 /* Horrible things: NMIs, double faults, MCEs */
829+
#define BAD_STACK 7 /* Horrible things: double faults, MCEs */
828830
#endif
829831

830832
.align 16
831833
idt:
832834
IDT( 0, TRAP, EXC_STACK); IDT( 1, TRAP, EXC_STACK)
833-
IDT( 2, TRAP, BAD_STACK); IDT( 3, TRAP, EXC_STACK)
835+
IDT( 2, TRAP, NMI_STACK); IDT( 3, TRAP, EXC_STACK)
834836
IDT( 4, TRAP, EXC_STACK); IDT( 5, TRAP, EXC_STACK)
835837
IDT( 6, TRAP, EXC_STACK); IDT( 7, TRAP, EXC_STACK)
836838
IDT( 8, TRAP, BAD_STACK); IDT( 9, TRAP, EXC_STACK)
@@ -1041,26 +1043,42 @@ gdt80: /* LGDT descriptor for long mode */
10411043
.align 16
10421044
_exception_stack:
10431045
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
1046+
.global _nmi_stack
1047+
.align 16
1048+
_nmi_stack:
1049+
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
10441050

10451051
#if CONFIG_MP_NUM_CPUS > 1
10461052
.global _exception_stack1
10471053
.align 16
10481054
_exception_stack1:
10491055
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
1056+
.global _nmi_stack1
1057+
.align 16
1058+
_nmi_stack1:
1059+
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
10501060
#endif
10511061

10521062
#if CONFIG_MP_NUM_CPUS > 2
10531063
.global _exception_stack2
10541064
.align 16
10551065
_exception_stack2:
10561066
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
1067+
.global _nmi_stack2
1068+
.align 16
1069+
_nmi_stack2:
1070+
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
10571071
#endif
10581072

10591073
#if CONFIG_MP_NUM_CPUS > 3
10601074
.global _exception_stack3
10611075
.align 16
10621076
_exception_stack3:
10631077
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
1078+
.global _nmi_stack3
1079+
.align 16
1080+
_nmi_stack3:
1081+
.fill CONFIG_X86_EXCEPTION_STACK_SIZE, 1, 0xAA
10641082
#endif
10651083

10661084
#ifdef CONFIG_X86_KPTI

arch/x86/core/offsets/intel64_offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ GEN_OFFSET_SYM(_thread_arch_t, ptables);
3737

3838
GEN_OFFSET_SYM(x86_tss64_t, ist1);
3939
GEN_OFFSET_SYM(x86_tss64_t, ist2);
40+
GEN_OFFSET_SYM(x86_tss64_t, ist6);
4041
GEN_OFFSET_SYM(x86_tss64_t, ist7);
4142
GEN_OFFSET_SYM(x86_tss64_t, cpu);
4243
#ifdef CONFIG_USERSPACE

0 commit comments

Comments
 (0)