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