Unverified Commit c52ded8c authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!356 x86/boot/compressed: Register dummy NMI handler in EFI boot loader, to avoid kdump crashes

Merge Pull Request from: @henryze 
 
The artificially test code causes the panic cpu to be under the mce context which cannot respond to interrupts(includes NMIs) for a long time. At this duration, watchdog timer could send NMI timeout interrupt to the cpu.

Until the panic cpu runs into the EFI loader, because of the function of switching page tables newly added by the community, the `iret` instruction let cpu restore the ability to respond to nmi interrupts, but the loader does not register the nmi interrupt handler in idt, that results an abnormal restart of the hardware, and the kdump process has been interrupted so far.

The repair patch registers the nmi handler for the EFI loader. After a page fault exits, even if nmi is raised, it can be processed correctly to ensure the smooth completion of the kdump process. 
 
Link:https://gitee.com/openeuler/kernel/pulls/356

 

Reviewed-by: default avatarWei Li <liwei391@huawei.com>
Reviewed-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 5ee27742 28410785
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -359,3 +359,15 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)
	 */
	add_identity_map(address, end);
}

void do_boot_nmi_fault(struct pt_regs *regs, unsigned long error_code)
{
	/*
	 * Default boot loader placeholder fault handler - there's no real
	 * kernel running yet, so there's not much we can do - but NMIs
	 * can arrive in a kdump scenario, for example by the NMI watchdog.
	 *
	 * Not having any handler would cause the CPU to silently reboot,
	 * so we do the second-worst thing here and ignore the NMI.
	 */
}
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ void load_stage2_idt(void)
{
	boot_idt_desc.address = (unsigned long)boot_idt;

	set_idt_entry(X86_TRAP_NMI, boot_nmi_fault);
	set_idt_entry(X86_TRAP_PF, boot_page_fault);

#ifdef CONFIG_AMD_MEM_ENCRYPT
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ SYM_FUNC_END(\name)
	.text
	.code64

EXCEPTION_HANDLER	boot_nmi_fault do_boot_nmi_fault error_code=0
EXCEPTION_HANDLER	boot_page_fault do_boot_page_fault error_code=1

#ifdef CONFIG_AMD_MEM_ENCRYPT
+1 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ extern gate_desc boot_idt[BOOT_IDT_ENTRIES];
extern struct desc_ptr boot_idt_desc;

/* IDT Entry Points */
void boot_nmi_fault(void);
void boot_page_fault(void);
void boot_stage1_vc(void);
void boot_stage2_vc(void);