* Jeremy Fitzhardinge (jeremy@xxxxxxxx) wrote:
Mathieu Desnoyers wrote:
+/*I got this right first go? I must be getting good at this...
+ * Only returns from a trap or exception to a NMI context (intra-privilege
+ * level near return) to the same SS and CS segments. Should be used
+ * upon trap or exception return when nested over a NMI context so no iret is
+ * issued. It takes care of modifying the eflags, rsp and returning to the
+ * previous function.
+ *
+ * The stack, at that point, looks like :
+ *
+ * 0(rsp) RIP
+ * 8(rsp) CS
+ * 16(rsp) EFLAGS
+ * 24(rsp) RSP
+ * 32(rsp) SS
+ *
+ * Upon execution :
+ * Copy EIP to the top of the return stack
+ * Update top of return stack address
+ * Pop eflags into the eflags register
+ * Make the return stack current
+ * Near return (popping the return address from the return stack)
+ */
+#define INTERRUPT_RETURN_NMI_SAFE pushq %rax; \
+ mov %rsp, %rax; \
+ mov 24+8(%rax), %rsp; \
+ pushq 0+8(%rax); \
+ pushq 16+8(%rax); \
+ movq (%rax), %rax; \
+ popfq; \
+ ret;
Yes, it looked good to me at least :)
Anyway, trailing ';', and perhaps use a consistent form for mov (either movq or mov in all three instances).
Ok, fixed. Here is the update.
The last issue standing would be the paravirt code. Any ideas about how
it's best to do it ? It would be good to be able to get the nmi-safe
version on bare metal, patched with a standard iret emulation in
paravirt code.