aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Amit <nadav.amit@gmail.com>2014-06-18 10:19:23 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-06-19 06:52:14 -0400
commit5777392e83c96e3a0799dd2985598e0fc76cf4aa (patch)
treeb9b9d7ee6afe5d0e1864750b292abd2bb11fea53
parent5381417f6a51293e7b8af1eb18aefa5d47976a71 (diff)
KVM: x86: check DR6/7 high-bits are clear only on long-mode
When the guest sets DR6 and DR7, KVM asserts the high 32-bits are clear, and otherwise injects a #GP exception. This exception should only be injected only if running in long-mode. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.h18
2 files changed, 19 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index a717c13b9466..b362a1a38e51 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5184,7 +5184,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
5184 return 1; 5184 return 1;
5185 kvm_register_write(vcpu, reg, val); 5185 kvm_register_write(vcpu, reg, val);
5186 } else 5186 } else
5187 if (kvm_set_dr(vcpu, dr, kvm_register_read(vcpu, reg))) 5187 if (kvm_set_dr(vcpu, dr, kvm_register_readl(vcpu, reg)))
5188 return 1; 5188 return 1;
5189 5189
5190 skip_emulated_instruction(vcpu); 5190 skip_emulated_instruction(vcpu);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 8c97bac9a895..c5b61a7eb144 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -47,6 +47,16 @@ static inline int is_long_mode(struct kvm_vcpu *vcpu)
47#endif 47#endif
48} 48}
49 49
50static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
51{
52 int cs_db, cs_l;
53
54 if (!is_long_mode(vcpu))
55 return false;
56 kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
57 return cs_l;
58}
59
50static inline bool mmu_is_nested(struct kvm_vcpu *vcpu) 60static inline bool mmu_is_nested(struct kvm_vcpu *vcpu)
51{ 61{
52 return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu; 62 return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu;
@@ -108,6 +118,14 @@ static inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
108 return false; 118 return false;
109} 119}
110 120
121static inline unsigned long kvm_register_readl(struct kvm_vcpu *vcpu,
122 enum kvm_reg reg)
123{
124 unsigned long val = kvm_register_read(vcpu, reg);
125
126 return is_64_bit_mode(vcpu) ? val : (u32)val;
127}
128
111void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); 129void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
112void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); 130void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
113int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); 131int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);