All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] KVM: x86: Emulator fixes
@ 2015-01-26  7:32 Nadav Amit
  2015-01-26  7:32 ` [PATCH 1/7] KVM: x86: Dirty the dest op page on cmpxchg emulation Nadav Amit
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Sorry for sending patches at the last minute. There is nothing critical in this
patch-set.  Yet, if you may want to incorporate something in 3.20 -
specifically 5 (small define mistakes) or 7 (which is somewhat affected by
recent changes).

Thanks for reviewing the patches.

Nadav Amit (7):
  KVM: x86: Dirty the dest op page on cmpxchg emulation
  KVM: x86: Wrong operand size for far ret
  KVM: x86: IRET emulation does not clear NMI masking
  KVM: x86: ARPL emulation can cause spurious exceptions
  KVM: x86: Fix defines in emulator.c
  KVM: x86: 32-bit wraparound read/write not emulated correctly
  KVM: x86: Emulation of call may use incorrect stack size

 arch/x86/include/asm/kvm_emulate.h |  1 +
 arch/x86/kvm/emulate.c             | 85 +++++++++++++++++++++++++++-----------
 arch/x86/kvm/x86.c                 |  8 ++++
 3 files changed, 71 insertions(+), 23 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/7] KVM: x86: Dirty the dest op page on cmpxchg emulation
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 2/7] KVM: x86: Wrong operand size for far ret Nadav Amit
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Intel SDM says for CMPXCHG: "To simplify the interface to the processor’s bus,
the destination operand receives a write cycle without regard to the result of
the comparison.". This means the destination page should be dirtied.

Fix it to by writing back the original value if cmpxchg failed.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ef23c1e..aa27254 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2205,12 +2205,15 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
 	fastop(ctxt, em_cmp);
 
 	if (ctxt->eflags & EFLG_ZF) {
-		/* Success: write back to memory. */
+		/* Success: write back to memory; no update of EAX */
+		ctxt->src.type = OP_NONE;
 		ctxt->dst.val = ctxt->src.orig_val;
 	} else {
 		/* Failure: write the value we saw to EAX. */
-		ctxt->dst.type = OP_REG;
-		ctxt->dst.addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
+		ctxt->src.type = OP_REG;
+		ctxt->src.addr.reg = reg_rmw(ctxt, VCPU_REGS_RAX);
+		ctxt->src.val = ctxt->dst.orig_val;
+		/* Create write-cycle to dest by writing the same value */
 		ctxt->dst.val = ctxt->dst.orig_val;
 	}
 	return X86EMUL_CONTINUE;
@@ -4157,7 +4160,7 @@ static const struct opcode twobyte_table[256] = {
 	F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
 	GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul),
 	/* 0xB0 - 0xB7 */
-	I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg),
+	I2bv(DstMem | SrcReg | ModRM | Lock | PageTable | SrcWrite, em_cmpxchg),
 	I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg),
 	F(DstMem | SrcReg | ModRM | BitOp | Lock, em_btr),
 	I(DstReg | SrcMemFAddr | ModRM | Src2FS, em_lseg),
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/7] KVM: x86: Wrong operand size for far ret
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
  2015-01-26  7:32 ` [PATCH 1/7] KVM: x86: Dirty the dest op page on cmpxchg emulation Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 3/7] KVM: x86: IRET emulation does not clear NMI masking Nadav Amit
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Indeed, Intel SDM specifically states that for the RET instruction "In 64-bit
mode, the default operation size of this instruction is the stack-address size,
i.e. 64 bits."

However, experiments show this is not the case. Here is for example objdump of
small 64-bit asm:

  4004f1:	ca 14 00             	lret   $0x14
  4004f4:	48 cb                	lretq
  4004f6:	48 ca 14 00          	lretq  $0x14

Therefore, remove the Stack flag from far-ret instructions.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index aa27254..dd71004 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -4062,8 +4062,8 @@ static const struct opcode opcode_table[256] = {
 	G(ByteOp, group11), G(0, group11),
 	/* 0xC8 - 0xCF */
 	I(Stack | SrcImmU16 | Src2ImmByte, em_enter), I(Stack, em_leave),
-	I(ImplicitOps | Stack | SrcImmU16, em_ret_far_imm),
-	I(ImplicitOps | Stack, em_ret_far),
+	I(ImplicitOps | SrcImmU16, em_ret_far_imm),
+	I(ImplicitOps, em_ret_far),
 	D(ImplicitOps), DI(SrcImmByte, intn),
 	D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret),
 	/* 0xD0 - 0xD7 */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/7] KVM: x86: IRET emulation does not clear NMI masking
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
  2015-01-26  7:32 ` [PATCH 1/7] KVM: x86: Dirty the dest op page on cmpxchg emulation Nadav Amit
  2015-01-26  7:32 ` [PATCH 2/7] KVM: x86: Wrong operand size for far ret Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 4/7] KVM: x86: ARPL emulation can cause spurious exceptions Nadav Amit
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

The IRET instruction should clear NMI masking, but the current implementation
does not do so.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/include/asm/kvm_emulate.h | 1 +
 arch/x86/kvm/emulate.c             | 1 +
 arch/x86/kvm/x86.c                 | 6 ++++++
 3 files changed, 8 insertions(+)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index eb18117..57a9d94 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -208,6 +208,7 @@ struct x86_emulate_ops {
 
 	void (*get_cpuid)(struct x86_emulate_ctxt *ctxt,
 			  u32 *eax, u32 *ebx, u32 *ecx, u32 *edx);
+	void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked);
 };
 
 typedef u32 __attribute__((vector_size(16))) sse128_t;
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index dd71004..fa3ca55 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2047,6 +2047,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
 
 	ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */
 	ctxt->eflags |= EFLG_RESERVED_ONE_MASK;
+	ctxt->ops->set_nmi_mask(ctxt, false);
 
 	return rc;
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index afa0815..cdd6606 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4963,6 +4963,11 @@ static void emulator_write_gpr(struct x86_emulate_ctxt *ctxt, unsigned reg, ulon
 	kvm_register_write(emul_to_vcpu(ctxt), reg, val);
 }
 
+static void emulator_set_nmi_mask(struct x86_emulate_ctxt *ctxt, bool masked)
+{
+	kvm_x86_ops->set_nmi_mask(emul_to_vcpu(ctxt), masked);
+}
+
 static const struct x86_emulate_ops emulate_ops = {
 	.read_gpr            = emulator_read_gpr,
 	.write_gpr           = emulator_write_gpr,
@@ -4998,6 +5003,7 @@ static const struct x86_emulate_ops emulate_ops = {
 	.put_fpu             = emulator_put_fpu,
 	.intercept           = emulator_intercept,
 	.get_cpuid           = emulator_get_cpuid,
+	.set_nmi_mask        = emulator_set_nmi_mask,
 };
 
 static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/7] KVM: x86: ARPL emulation can cause spurious exceptions
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
                   ` (2 preceding siblings ...)
  2015-01-26  7:32 ` [PATCH 3/7] KVM: x86: IRET emulation does not clear NMI masking Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 5/7] KVM: x86: Fix defines in emulator.c Nadav Amit
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

ARPL and MOVSXD are encoded the same and their execution depends on the
execution mode.  The operand sizes of each instruction are different.
Currently, ARPL is detected too late, after the decoding was already done, and
therefore may result in spurious exception (instead of failed emulation).

Introduce a group to the emulator to handle instructions according to execution
mode (32/64 bits). Note: in order not to make changes that may affect
performance, the new ModeDual can only be applied to instructions with ModRM.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index fa3ca55..db3cf39 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -125,6 +125,7 @@
 #define RMExt       (4<<15)     /* Opcode extension in ModRM r/m if mod == 3 */
 #define Escape      (5<<15)     /* Escape to coprocessor instruction */
 #define InstrDual   (6<<15)     /* Alternate instruction decoding of mod == 3 */
+#define ModeDual    (7<<15)     /* Different instruction for 32/64 bit */
 #define Sse         (1<<18)     /* SSE Vector instruction */
 /* Generic ModRM decode. */
 #define ModRM       (1<<19)
@@ -215,6 +216,7 @@ struct opcode {
 		const struct gprefix *gprefix;
 		const struct escape *esc;
 		const struct instr_dual *idual;
+		const struct mode_dual *mdual;
 		void (*fastop)(struct fastop *fake);
 	} u;
 	int (*check_perm)(struct x86_emulate_ctxt *ctxt);
@@ -242,6 +244,11 @@ struct instr_dual {
 	struct opcode mod3;
 };
 
+struct mode_dual {
+	struct opcode mode32;
+	struct opcode mode64;
+};
+
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
 #define EFLG_VIP (1<<20)
@@ -3530,6 +3537,12 @@ static int em_clflush(struct x86_emulate_ctxt *ctxt)
 	return X86EMUL_CONTINUE;
 }
 
+static int em_movsxd(struct x86_emulate_ctxt *ctxt)
+{
+	ctxt->dst.val = (s32) ctxt->src.val;
+	return X86EMUL_CONTINUE;
+}
+
 static bool valid_cr(int nr)
 {
 	switch (nr) {
@@ -3729,6 +3742,7 @@ static int check_perm_out(struct x86_emulate_ctxt *ctxt)
 #define G(_f, _g) { .flags = ((_f) | Group | ModRM), .u.group = (_g) }
 #define GD(_f, _g) { .flags = ((_f) | GroupDual | ModRM), .u.gdual = (_g) }
 #define ID(_f, _i) { .flags = ((_f) | InstrDual | ModRM), .u.idual = (_i) }
+#define MD(_f, _m) { .flags = ((_f) | ModeDual), .u.mdual = (_m) }
 #define E(_f, _e) { .flags = ((_f) | Escape | ModRM), .u.esc = (_e) }
 #define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
 #define F(_f, _e) { .flags = (_f) | Fastop, .u.fastop = (_e) }
@@ -3973,6 +3987,10 @@ static const struct instr_dual instr_dual_0f_c3 = {
 	I(DstMem | SrcReg | ModRM | No16 | Mov, em_mov), N
 };
 
+static const struct mode_dual mode_dual_63 = {
+	N, I(DstReg | SrcMem32 | ModRM | Mov, em_movsxd)
+};
+
 static const struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
 	F6ALU(Lock, em_add),
@@ -4007,7 +4025,7 @@ static const struct opcode opcode_table[256] = {
 	/* 0x60 - 0x67 */
 	I(ImplicitOps | Stack | No64, em_pusha),
 	I(ImplicitOps | Stack | No64, em_popa),
-	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
+	N, MD(ModRM, &mode_dual_63),
 	N, N, N, N,
 	/* 0x68 - 0x6F */
 	I(SrcImm | Mov | Stack, em_push),
@@ -4227,6 +4245,7 @@ static const struct opcode opcode_map_0f_38[256] = {
 #undef I
 #undef GP
 #undef EXT
+#undef MD
 
 #undef D2bv
 #undef D2bvIP
@@ -4616,6 +4635,12 @@ done_prefixes:
 			else
 				opcode = opcode.u.idual->mod012;
 			break;
+		case ModeDual:
+			if (ctxt->mode == X86EMUL_MODE_PROT64)
+				opcode = opcode.u.mdual->mode64;
+			else
+				opcode = opcode.u.mdual->mode32;
+			break;
 		default:
 			return EMULATION_FAILED;
 		}
@@ -4956,11 +4981,6 @@ special_insn:
 		goto threebyte_insn;
 
 	switch (ctxt->b) {
-	case 0x63:		/* movsxd */
-		if (ctxt->mode != X86EMUL_MODE_PROT64)
-			goto cannot_emulate;
-		ctxt->dst.val = (s32) ctxt->src.val;
-		break;
 	case 0x70 ... 0x7f: /* jcc (short) */
 		if (test_cc(ctxt->b, ctxt->eflags))
 			rc = jmp_rel(ctxt, ctxt->src.val);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/7] KVM: x86: Fix defines in emulator.c
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
                   ` (3 preceding siblings ...)
  2015-01-26  7:32 ` [PATCH 4/7] KVM: x86: ARPL emulation can cause spurious exceptions Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 6/7] KVM: x86: 32-bit wraparound read/write not emulated correctly Nadav Amit
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Unnecassary define was left after commit 7d882ffa81d5 ("KVM: x86: Revert
NoBigReal patch in the emulator”).

Commit 39f062ff51b2 ("KVM: x86: Generate #UD when memory operand is required”)
was missing undef.

Fix it.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index db3cf39..997c9eb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -167,7 +167,6 @@
 #define NoMod	    ((u64)1 << 47)  /* Mod field is ignored */
 #define Intercept   ((u64)1 << 48)  /* Has valid intercept field */
 #define CheckPerm   ((u64)1 << 49)  /* Has valid check_perm field */
-#define NoBigReal   ((u64)1 << 50)  /* No big real mode */
 #define PrivUD      ((u64)1 << 51)  /* #UD instead of #GP on CPL > 0 */
 #define NearBranch  ((u64)1 << 52)  /* Near branches */
 #define No16	    ((u64)1 << 53)  /* No 16 bit operand */
@@ -4246,6 +4245,7 @@ static const struct opcode opcode_map_0f_38[256] = {
 #undef GP
 #undef EXT
 #undef MD
+#undef ID
 
 #undef D2bv
 #undef D2bvIP
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/7] KVM: x86: 32-bit wraparound read/write not emulated correctly
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
                   ` (4 preceding siblings ...)
  2015-01-26  7:32 ` [PATCH 5/7] KVM: x86: Fix defines in emulator.c Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26  7:32 ` [PATCH 7/7] KVM: x86: Emulation of call may use incorrect stack size Nadav Amit
  2015-01-26 11:19 ` [PATCH 0/7] KVM: x86: Emulator fixes Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

If we got a wraparound of 32-bit operand, and the limit is 0xffffffff, read and
writes should be successful. It just needs to be done in two segments.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 10 +++++++---
 arch/x86/kvm/x86.c     |  2 ++
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 997c9eb..c3b0757 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -684,9 +684,13 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 		}
 		if (addr.ea > lim)
 			goto bad;
-		*max_size = min_t(u64, ~0u, (u64)lim + 1 - addr.ea);
-		if (size > *max_size)
-			goto bad;
+		if (lim == 0xffffffff)
+			*max_size = ~0u;
+		else {
+			*max_size = (u64)lim + 1 - addr.ea;
+			if (size > *max_size)
+				goto bad;
+		}
 		la &= (u32)-1;
 		break;
 	}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cdd6606..1e10e3f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4495,6 +4495,8 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		addr += now;
+		if (ctxt->mode != X86EMUL_MODE_PROT64)
+			addr = (u32)addr;
 		val += now;
 		bytes -= now;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/7] KVM: x86: Emulation of call may use incorrect stack size
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
                   ` (5 preceding siblings ...)
  2015-01-26  7:32 ` [PATCH 6/7] KVM: x86: 32-bit wraparound read/write not emulated correctly Nadav Amit
@ 2015-01-26  7:32 ` Nadav Amit
  2015-01-26 11:19 ` [PATCH 0/7] KVM: x86: Emulator fixes Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2015-01-26  7:32 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

On long-mode, when far call that changes cs.l takes place, the stack size is
determined by the new mode.  For instance, if we go from 32-bit mode to 64-bit
mode, the stack-size if 64.  KVM uses the old stack size.

Fix it.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
---
 arch/x86/kvm/emulate.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c3b0757..81dcf79 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -741,19 +741,26 @@ static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
 			  const struct desc_struct *cs_desc)
 {
 	enum x86emul_mode mode = ctxt->mode;
+	int rc;
 
 #ifdef CONFIG_X86_64
-	if (ctxt->mode >= X86EMUL_MODE_PROT32 && cs_desc->l) {
-		u64 efer = 0;
+	if (ctxt->mode >= X86EMUL_MODE_PROT16) {
+		if (cs_desc->l) {
+			u64 efer = 0;
 
-		ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
-		if (efer & EFER_LMA)
-			mode = X86EMUL_MODE_PROT64;
+			ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+			if (efer & EFER_LMA)
+				mode = X86EMUL_MODE_PROT64;
+		} else
+			mode = X86EMUL_MODE_PROT32; /* temporary value */
 	}
 #endif
 	if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32)
 		mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
-	return assign_eip(ctxt, dst, mode);
+	rc = assign_eip(ctxt, dst, mode);
+	if (rc == X86EMUL_CONTINUE)
+		ctxt->mode = mode;
+	return rc;
 }
 
 static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
@@ -3062,6 +3069,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
 	struct desc_struct old_desc, new_desc;
 	const struct x86_emulate_ops *ops = ctxt->ops;
 	int cpl = ctxt->ops->cpl(ctxt);
+	enum x86emul_mode prev_mode = ctxt->mode;
 
 	old_eip = ctxt->_eip;
 	ops->get_segment(ctxt, &old_cs, &old_desc, NULL, VCPU_SREG_CS);
@@ -3085,11 +3093,14 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
 	rc = em_push(ctxt);
 	/* If we failed, we tainted the memory, but the very least we should
 	   restore cs */
-	if (rc != X86EMUL_CONTINUE)
+	if (rc != X86EMUL_CONTINUE) {
+		pr_warn_once("faulting far call emulation tainted memory\n");
 		goto fail;
+	}
 	return rc;
 fail:
 	ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
+	ctxt->mode = prev_mode;
 	return rc;
 
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/7] KVM: x86: Emulator fixes
  2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
                   ` (6 preceding siblings ...)
  2015-01-26  7:32 ` [PATCH 7/7] KVM: x86: Emulation of call may use incorrect stack size Nadav Amit
@ 2015-01-26 11:19 ` Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2015-01-26 11:19 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm



On 26/01/2015 08:32, Nadav Amit wrote:
> Sorry for sending patches at the last minute. There is nothing critical in this
> patch-set.  Yet, if you may want to incorporate something in 3.20 -
> specifically 5 (small define mistakes) or 7 (which is somewhat affected by
> recent changes).
> 
> Thanks for reviewing the patches.

I'll apply all of them for 3.20, since Linus expects no merge window for
2 weeks.

Paolo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-01-26 11:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-26  7:32 [PATCH 0/7] KVM: x86: Emulator fixes Nadav Amit
2015-01-26  7:32 ` [PATCH 1/7] KVM: x86: Dirty the dest op page on cmpxchg emulation Nadav Amit
2015-01-26  7:32 ` [PATCH 2/7] KVM: x86: Wrong operand size for far ret Nadav Amit
2015-01-26  7:32 ` [PATCH 3/7] KVM: x86: IRET emulation does not clear NMI masking Nadav Amit
2015-01-26  7:32 ` [PATCH 4/7] KVM: x86: ARPL emulation can cause spurious exceptions Nadav Amit
2015-01-26  7:32 ` [PATCH 5/7] KVM: x86: Fix defines in emulator.c Nadav Amit
2015-01-26  7:32 ` [PATCH 6/7] KVM: x86: 32-bit wraparound read/write not emulated correctly Nadav Amit
2015-01-26  7:32 ` [PATCH 7/7] KVM: x86: Emulation of call may use incorrect stack size Nadav Amit
2015-01-26 11:19 ` [PATCH 0/7] KVM: x86: Emulator fixes Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.