3e20b48
From: Nadav Amit <namit@cs.technion.ac.il>
3e20b48
Date: Fri, 24 Oct 2014 17:07:15 +0200
3e20b48
Subject: [PATCH] KVM: x86: Fix wrong masking on relative jump/call
3e20b48
3e20b48
Relative jumps and calls do the masking according to the operand size, and not
3e20b48
according to the address size as the KVM emulator does today.
3e20b48
3e20b48
This patch fixes KVM behavior.
3e20b48
3e20b48
Cc: stable@vger.kernel.org
3e20b48
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
3e20b48
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
3e20b48
---
3e20b48
 arch/x86/kvm/emulate.c | 27 ++++++++++++++++++++++-----
3e20b48
 1 file changed, 22 insertions(+), 5 deletions(-)
3e20b48
3e20b48
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
3e20b48
index 03954f7900f5..a85f438b6a47 100644
3e20b48
--- a/arch/x86/kvm/emulate.c
3e20b48
+++ b/arch/x86/kvm/emulate.c
3e20b48
@@ -504,11 +504,6 @@ static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
3e20b48
 	masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc);
3e20b48
 }
3e20b48
 
3e20b48
-static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
3e20b48
-{
3e20b48
-	register_address_increment(ctxt, &ctxt->_eip, rel);
3e20b48
-}
3e20b48
-
3e20b48
 static u32 desc_limit_scaled(struct desc_struct *desc)
3e20b48
 {
3e20b48
 	u32 limit = get_desc_limit(desc);
3e20b48
@@ -568,6 +563,28 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
3e20b48
 	return emulate_exception(ctxt, NM_VECTOR, 0, false);
3e20b48
 }
3e20b48
 
3e20b48
+static inline void assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
3e20b48
+{
3e20b48
+	switch (ctxt->op_bytes) {
3e20b48
+	case 2:
3e20b48
+		ctxt->_eip = (u16)dst;
3e20b48
+		break;
3e20b48
+	case 4:
3e20b48
+		ctxt->_eip = (u32)dst;
3e20b48
+		break;
3e20b48
+	case 8:
3e20b48
+		ctxt->_eip = dst;
3e20b48
+		break;
3e20b48
+	default:
3e20b48
+		WARN(1, "unsupported eip assignment size\n");
3e20b48
+	}
3e20b48
+}
3e20b48
+
3e20b48
+static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
3e20b48
+{
3e20b48
+	assign_eip_near(ctxt, ctxt->_eip + rel);
3e20b48
+}
3e20b48
+
3e20b48
 static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
3e20b48
 {
3e20b48
 	u16 selector;
3e20b48
-- 
3e20b48
1.9.3
3e20b48