Re: [RFC PATCH 4/4] x86/entry/nmi: unmask NMIs on userspace NMI when entry debugging

From: Andy Lutomirski
Date: Thu Jun 03 2021 - 13:38:36 EST


On 5/31/21 11:52 PM, Lai Jiangshan wrote:
> From: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx>

Why?

>
> Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx>
> ---
> arch/x86/entry/entry_64.S | 36 ++++++++++++++++++++----------------
> 1 file changed, 20 insertions(+), 16 deletions(-)
>
> diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
> index f54e06139d4b..309e63f4f391 100644
> --- a/arch/x86/entry/entry_64.S
> +++ b/arch/x86/entry/entry_64.S
> @@ -1055,6 +1055,24 @@ SYM_CODE_START_LOCAL(error_return)
> jmp swapgs_restore_regs_and_return_to_usermode
> SYM_CODE_END(error_return)
>
> +.macro debug_entry_unmask_NMIs
> +#ifdef CONFIG_DEBUG_ENTRY
> + /*
> + * For ease of testing, unmask NMIs right away. Disabled by
> + * default because IRET is very expensive.
> + */
> + pushq $0 /* SS */
> + pushq %rsp /* RSP (minus 8 because of the previous push) */
> + addq $8, (%rsp) /* Fix up RSP */
> + pushfq /* RFLAGS */
> + pushq $__KERNEL_CS /* CS */
> + pushq $1f /* RIP */
> + iretq /* continues with NMI unmasked */
> + UNWIND_HINT_IRET_REGS
> +1:
> +#endif
> +.endm
> +
> /*
> * Runs on exception stack. Xen PV does not go through this path at all,
> * so we can use real assembly here.
> @@ -1145,6 +1163,7 @@ SYM_CODE_START(asm_exc_nmi)
> * At this point we no longer need to worry about stack damage
> * due to nesting -- we're done with the NMI stack.
> */
> + debug_entry_unmask_NMIs
> pushq $-1 /* pt_regs->orig_ax */
> idtentry_body exc_nmi has_error_code=0
>
> @@ -1286,22 +1305,7 @@ first_nmi:
> UNWIND_HINT_IRET_REGS
>
> /* Everything up to here is safe from nested NMIs */
> -
> -#ifdef CONFIG_DEBUG_ENTRY
> - /*
> - * For ease of testing, unmask NMIs right away. Disabled by
> - * default because IRET is very expensive.
> - */
> - pushq $0 /* SS */
> - pushq %rsp /* RSP (minus 8 because of the previous push) */
> - addq $8, (%rsp) /* Fix up RSP */
> - pushfq /* RFLAGS */
> - pushq $__KERNEL_CS /* CS */
> - pushq $1f /* RIP */
> - iretq /* continues at repeat_nmi below */
> - UNWIND_HINT_IRET_REGS
> -1:
> -#endif
> + debug_entry_unmask_NMIs
>
> repeat_nmi:
> /*
>