Messages in this thread | | | Subject | Perhaps a side effect regarding NMI returns | From | Steven Rostedt <> | Date | Mon, 28 Nov 2011 23:07:53 -0500 |
| |
I was looking at the return sequence of NMIs in x86_64 and I came across this in entry_64.S:
jz paranoid_swapgs movq %rsp,%rdi /* &pt_regs */ call sync_regs movq %rax,%rsp /* switch stack for scheduling */ testl $_TIF_NEED_RESCHED,%ebx jnz paranoid_schedule movl %ebx,%edx /* arg3: thread flags */ TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_NONE) xorl %esi,%esi /* arg2: oldset */ movq %rsp,%rdi /* arg1: &pt_regs */ call do_notify_resume DISABLE_INTERRUPTS(CLBR_NONE) TRACE_IRQS_OFF jmp paranoid_userspace paranoid_schedule: TRACE_IRQS_ON ENABLE_INTERRUPTS(CLBR_ANY) call schedule DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF jmp paranoid_userspace CFI_ENDPROC
Specifically the code after jnz paranoid_schedule.
Just before that jnz, we swap the stack back to the task's stack (no more NMI stack). If NEED_RESCHED is set, we jump to paranoid_schedule and enable interrupts and call schedule.
Is there a bit of a side effect here? What happens when you enable interrupts in NMI context? Can more NMIs come in? If not, we just went into schedule and went off and running, and NMIs will have to wait till the next interrupt comes in and calls iretq to re-enable NMIs. If we lock up here, don't expect NMI watchdog to help you out.
If enabling interrupts also enables NMIs, then there's no side effect.
This email is more of an FYI than anything else. Maybe there's an issue here, and maybe there isn't. But this is so subtle that I figured I would bring it to other people's attention. I'll let others do the hard work to figure out if we should worry about this or not ;-)
-- Steve
| |