A 64bit IRET can restore NT - the faulting case is when NT is set in the live
flags. This change had an unintended consequence of causing the NT flag to
spontaneously disappear from guest context whenever a interrupt/exception
occurred.
In combination with a SYSENTER which sets both TF and NT, Xen's handling of
the #DB exceptions clears NT before it is even recorded suitably in the guest
kernel's view of what userspace was doing.
Reported-by: Andy Lutomirski <luto@kernel.org>
Fixes: 0e47f92b0 ("x86: force EFLAGS.IF on when exiting to PV guests")
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
/* %rbx: struct vcpu, interrupts disabled */
ENTRY(compat_restore_all_guest)
ASSERT_INTERRUPTS_DISABLED
- mov $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),%r11d
+ mov $~(X86_EFLAGS_IOPL | X86_EFLAGS_VM), %r11d
and UREGS_eflags(%rsp),%r11d
.macro alt_cr4_pv32
jz iret_exit_to_guest
movq 24(%rsp),%r11 # RFLAGS
- andq $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),%r11
+ andq $~(X86_EFLAGS_IOPL | X86_EFLAGS_VM), %r11
orq $X86_EFLAGS_IF,%r11
/* Don't use SYSRET path if the return address is not canonical. */
movq 8(%rsp), %rcx # RIP
/* No special register assumptions. */
iret_exit_to_guest:
- andl $~(X86_EFLAGS_IOPL|X86_EFLAGS_NT|X86_EFLAGS_VM),24(%rsp)
+ andl $~(X86_EFLAGS_IOPL | X86_EFLAGS_VM), 24(%rsp)
orl $X86_EFLAGS_IF,24(%rsp)
addq $8,%rsp
.Lft0: iretq