x86/pv: Don't clobber NT on return-to-guest

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>
master commit: 5bcac98549
master date: 2020-09-24 21:02:35 +0100
This commit is contained in:
Andrew Cooper authored and Jan Beulich committed 2020-10-20 14:41:04 +02:00
1 parent a279fcbb4f
commit 0974e0085d
2 files changed
+3 -3

No files matched your search

+1 -1
View File
@@ -119,7 +119,7 @@ compat_process_trap:
/* %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
+2 -2
View File
@@ -182,7 +182,7 @@ restore_all_guest:
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. */
@@ -213,7 +213,7 @@ restore_all_guest:
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.