Make sure DR4 and DR5 are aliased to DR6 and DR7, respectively, if
CR4.DE is not set.

Signed-off-by: Jan Kiszka <[email protected]>
---

 arch/x86/kvm/vmx.c |   33 ++++++++++++++++++++++++++-------
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7012680..d34aea5 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2963,14 +2963,24 @@ static int handle_dr(struct kvm_vcpu *vcpu)
                case 0 ... 3:
                        val = vcpu->arch.db[dr];
                        break;
+               case 4:
+                       if (vcpu->arch.cr4 & X86_CR4_DE) {
+                               kvm_queue_exception(vcpu, UD_VECTOR);
+                               goto skip_instr;
+                       }
+                       /* fall through */
                case 6:
                        val = vcpu->arch.dr6;
                        break;
-               case 7:
+               case 5:
+                       if (vcpu->arch.cr4 & X86_CR4_DE) {
+                               kvm_queue_exception(vcpu, UD_VECTOR);
+                               goto skip_instr;
+                       }
+                       /* fall through */
+               default: /* 7 */
                        val = vcpu->arch.dr7;
                        break;
-               default:
-                       val = 0;
                }
                kvm_register_write(vcpu, reg, val);
        } else {
@@ -2981,10 +2991,12 @@ static int handle_dr(struct kvm_vcpu *vcpu)
                        if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
                                vcpu->arch.eff_db[dr] = val;
                        break;
-               case 4 ... 5:
-                       if (vcpu->arch.cr4 & X86_CR4_DE)
+               case 4:
+                       if (vcpu->arch.cr4 & X86_CR4_DE) {
                                kvm_queue_exception(vcpu, UD_VECTOR);
-                       break;
+                               break;
+                       }
+                       /* fall through */
                case 6:
                        if (val & 0xffffffff00000000ULL) {
                                kvm_queue_exception(vcpu, GP_VECTOR);
@@ -2992,7 +3004,13 @@ static int handle_dr(struct kvm_vcpu *vcpu)
                        }
                        vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
                        break;
-               case 7:
+               case 5:
+                       if (vcpu->arch.cr4 & X86_CR4_DE) {
+                               kvm_queue_exception(vcpu, UD_VECTOR);
+                               break;
+                       }
+                       /* fall through */
+               default: /* 7 */
                        if (val & 0xffffffff00000000ULL) {
                                kvm_queue_exception(vcpu, GP_VECTOR);
                                break;
@@ -3006,6 +3024,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
                        break;
                }
        }
+skip_instr:
        skip_emulated_instruction(vcpu);
        return 1;
 }

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to