1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
From 7e636b8a16412d4f0d94b2b24d7ebcd2c749afff Mon Sep 17 00:00:00 2001
From: Jan Beulich <jbeulich@suse.com>
Date: Thu, 4 Jul 2024 14:14:49 +0200
Subject: [PATCH 51/56] x86/entry: don't clear DF when raising #UD for lack of
syscall handler
While doing so is intentional when invoking the actual callback, to
mimic a hard-coded SYCALL_MASK / FMASK MSR, the same should not be done
when no handler is available and hence #UD is raised.
Fixes: ca6fcf4321b3 ("x86/pv: Inject #UD for missing SYSCALL callbacks")
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
master commit: d2fe9ab3048d503869ec81bc49db07e55a4a2386
master date: 2024-07-02 12:01:21 +0200
---
xen/arch/x86/x86_64/entry.S | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 054fcb225f..d3def49ea3 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -38,6 +38,14 @@ switch_to_kernel:
setc %cl
leal (,%rcx,TBF_INTERRUPT),%ecx
+ /*
+ * The PV ABI hardcodes the (guest-inaccessible and virtual)
+ * SYSCALL_MASK MSR such that DF (and nothing else) would be cleared.
+ * Note that the equivalent of IF (VGCF_syscall_disables_events) is
+ * dealt with separately above.
+ */
+ mov $~X86_EFLAGS_DF, %esi
+
test %rax, %rax
UNLIKELY_START(z, syscall_no_callback) /* TB_eip == 0 => #UD */
mov VCPU_trap_ctxt(%rbx), %rdi
@@ -47,12 +55,14 @@ UNLIKELY_START(z, syscall_no_callback) /* TB_eip == 0 => #UD */
testb $4, X86_EXC_UD * TRAPINFO_sizeof + TRAPINFO_flags(%rdi)
setnz %cl
lea TBF_EXCEPTION(, %rcx, TBF_INTERRUPT), %ecx
+ or $~0, %esi /* Don't clear DF */
UNLIKELY_END(syscall_no_callback)
movq %rax,TRAPBOUNCE_eip(%rdx)
movb %cl,TRAPBOUNCE_flags(%rdx)
call create_bounce_frame
- andl $~X86_EFLAGS_DF,UREGS_eflags(%rsp)
+ /* Conditionally clear DF */
+ and %esi, UREGS_eflags(%rsp)
/* %rbx: struct vcpu */
test_all_events:
ASSERT_NOT_IN_ATOMIC
--
2.45.2
|