diff mbox

[4/6] KVM: VMX: Fix emulation of DR4 and DR5

Message ID 20090904125119.18939.29087.stgit@mchn012c.ww002.siemens.net (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka Sept. 4, 2009, 12:51 p.m. UTC
Make sure DR4 and DR5 are aliased to DR6 and DR7, respectively, if
CR4.DE is not set.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

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


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

Patch

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;
 }