1 |
From 780079c8c61ea452198d8cd3f0363543ee84d7fc Mon Sep 17 00:00:00 2001 |
2 |
From: Jim Mattson <jmattson@google.com> |
3 |
Date: Fri, 21 Sep 2018 10:36:17 -0700 |
4 |
Subject: [PATCH 094/145] KVM: nVMX: Clear reserved bits of #DB exit |
5 |
qualification |
6 |
|
7 |
[ Upstream commit cfb634fe3052aefc4e1360fa322018c9a0b49755 ] |
8 |
|
9 |
According to volume 3 of the SDM, bits 63:15 and 12:4 of the exit |
10 |
qualification field for debug exceptions are reserved (cleared to |
11 |
0). However, the SDM is incorrect about bit 16 (corresponding to |
12 |
DR6.RTM). This bit should be set if a debug exception (#DB) or a |
13 |
breakpoint exception (#BP) occurred inside an RTM region while |
14 |
advanced debugging of RTM transactional regions was enabled. Note that |
15 |
this is the opposite of DR6.RTM, which "indicates (when clear) that a |
16 |
debug exception (#DB) or breakpoint exception (#BP) occurred inside an |
17 |
RTM region while advanced debugging of RTM transactional regions was |
18 |
enabled." |
19 |
|
20 |
There is still an issue with stale DR6 bits potentially being |
21 |
misreported for the current debug exception. DR6 should not have been |
22 |
modified before vectoring the #DB exception, and the "new DR6 bits" |
23 |
should be available somewhere, but it was and they aren't. |
24 |
|
25 |
Fixes: b96fb439774e1 ("KVM: nVMX: fixes to nested virt interrupt injection") |
26 |
Signed-off-by: Jim Mattson <jmattson@google.com> |
27 |
Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com> |
28 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
29 |
Signed-off-by: Sasha Levin <sashal@kernel.org> |
30 |
--- |
31 |
arch/x86/include/asm/kvm_host.h | 1 + |
32 |
arch/x86/kvm/vmx.c | 7 +++++-- |
33 |
2 files changed, 6 insertions(+), 2 deletions(-) |
34 |
|
35 |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h |
36 |
index 09b2e3e2cf1b..1c09a0d1771f 100644 |
37 |
--- a/arch/x86/include/asm/kvm_host.h |
38 |
+++ b/arch/x86/include/asm/kvm_host.h |
39 |
@@ -177,6 +177,7 @@ enum { |
40 |
|
41 |
#define DR6_BD (1 << 13) |
42 |
#define DR6_BS (1 << 14) |
43 |
+#define DR6_BT (1 << 15) |
44 |
#define DR6_RTM (1 << 16) |
45 |
#define DR6_FIXED_1 0xfffe0ff0 |
46 |
#define DR6_INIT 0xffff0ff0 |
47 |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c |
48 |
index e665aa7167cf..a933ce5ec1ff 100644 |
49 |
--- a/arch/x86/kvm/vmx.c |
50 |
+++ b/arch/x86/kvm/vmx.c |
51 |
@@ -3294,10 +3294,13 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned long *exit |
52 |
} |
53 |
} else { |
54 |
if (vmcs12->exception_bitmap & (1u << nr)) { |
55 |
- if (nr == DB_VECTOR) |
56 |
+ if (nr == DB_VECTOR) { |
57 |
*exit_qual = vcpu->arch.dr6; |
58 |
- else |
59 |
+ *exit_qual &= ~(DR6_FIXED_1 | DR6_BT); |
60 |
+ *exit_qual ^= DR6_RTM; |
61 |
+ } else { |
62 |
*exit_qual = 0; |
63 |
+ } |
64 |
return 1; |
65 |
} |
66 |
} |
67 |
-- |
68 |
2.19.1 |
69 |
|