kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup
@ 2014-11-19 15:43 Nadav Amit
  2014-11-19 15:43 ` [PATCH 1/6] KVM: x86: Revert NoBigReal patch in the emulator Nadav Amit
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

This patch-set fixes 4 bugs in the __linearize emulator function, and makes
some cleanup of the function.

Patches 2 to 5 deal with separate bugs.

Patch 1 and 6 introduce minor enhancement and have no functional implications.
The first patch reverts a patch which was written by this patch author. The
last is a minor cleanup of __linearize.

Thanks for reviewing the patch-set.

Nadav Amit (6):
  KVM: x86: Revert NoBigReal patch in the emulator
  KVM: x86: Stack size is overridden by __linearize
  KVM: x86: Emulator performs privilege checks on __linearize
  KVM: x86: Perform limit checks when assigning EIP
  KVM: x86: Non-canonical access using SS should cause #SS
  KVM: x86: Move __linearize masking of la into switch

 arch/x86/kvm/emulate.c | 132 +++++++++++++++++++++++--------------------------
 1 file changed, 62 insertions(+), 70 deletions(-)

-- 
1.9.1


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

* [PATCH 1/6] KVM: x86: Revert NoBigReal patch in the emulator
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 15:43 ` [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize Nadav Amit
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

Commit 10e38fc7cab6 ("KVM: x86: Emulator flag for instruction that only support
16-bit addresses in real mode") introduced NoBigReal for instructions such as
MONITOR. Apparetnly, the Intel SDM description that led to this patch is
misleading.  Since no instruction is using NoBigReal, it is safe to remove it,
we fully understand what the SDM means.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index e020fed..5d47714 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -690,13 +690,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 		if (!fetch && (desc.type & 8) && !(desc.type & 2))
 			goto bad;
 		lim = desc_limit_scaled(&desc);
-		if ((ctxt->mode == X86EMUL_MODE_REAL) && !fetch &&
-		    (ctxt->d & NoBigReal)) {
-			/* la is between zero and 0xffff */
-			if (la > 0xffff)
-				goto bad;
-			*max_size = 0x10000 - la;
-		} else if ((desc.type & 8) || !(desc.type & 4)) {
+		if ((desc.type & 8) || !(desc.type & 4)) {
 			/* expand-up segment */
 			if (addr.ea > lim)
 				goto bad;
-- 
1.9.1


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

* [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
  2014-11-19 15:43 ` [PATCH 1/6] KVM: x86: Revert NoBigReal patch in the emulator Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 17:17   ` Paolo Bonzini
  2014-11-19 15:43 ` [PATCH 3/6] KVM: x86: Emulator performs privilege checks on __linearize Nadav Amit
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

When performing segmented-read/write in the emulator for stack operations, it
ignores the stack size, and uses the ad_bytes as indication for the pointer
size. As a result, a wrong address may be accessed.

To fix this behavior, we can remove the masking of address in __linearize and
perform it beforehand.  It is already done for the operands (so currently it is
inefficiently done twice). It is missing in two cases:
1. When using rip_relative
2. On fetch_bit_operand that changes the address.

This patch masks the address on these two occassions, and removes the masking
from __linearize.

Note that it does not mask EIP during fetch. In protected/legacy mode code
fetch when RIP >= 2^32 should result in #GP and not wrap-around. Since we make
limit checks within __linearize, this is the expected behavior.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 5d47714..1317560 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -665,8 +665,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 	u16 sel;
 	unsigned cpl;
 
-	la = seg_base(ctxt, addr.seg) +
-	    (fetch || ctxt->ad_bytes == 8 ? addr.ea : (u32)addr.ea);
+	la = seg_base(ctxt, addr.seg) + addr.ea;
 	*max_size = 0;
 	switch (ctxt->mode) {
 	case X86EMUL_MODE_PROT64:
@@ -1289,7 +1288,8 @@ static void fetch_bit_operand(struct x86_emulate_ctxt *ctxt)
 		else
 			sv = (s64)ctxt->src.val & (s64)mask;
 
-		ctxt->dst.addr.mem.ea += (sv >> 3);
+		ctxt->dst.addr.mem.ea = address_mask(ctxt,
+					   ctxt->dst.addr.mem.ea + (sv >> 3));
 	}
 
 	/* only subword offset */
@@ -4638,7 +4638,8 @@ done_prefixes:
 	rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
 
 	if (ctxt->rip_relative)
-		ctxt->memopp->addr.mem.ea += ctxt->_eip;
+		ctxt->memopp->addr.mem.ea = address_mask(ctxt,
+					ctxt->memopp->addr.mem.ea + ctxt->_eip);
 
 done:
 	return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
-- 
1.9.1


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

* [PATCH 3/6] KVM: x86: Emulator performs privilege checks on __linearize
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
  2014-11-19 15:43 ` [PATCH 1/6] KVM: x86: Revert NoBigReal patch in the emulator Nadav Amit
  2014-11-19 15:43 ` [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 15:43 ` [PATCH 4/6] KVM: x86: Perform limit checks when assigning EIP Nadav Amit
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

When segment is accessed, real hardware does not perform any privilege level
checks.  In contrast, KVM emulator does. This causes some discrepencies from
real hardware. For instance, reading from readable code segment may fail due to
incorrect segment checks. In addition, it introduces unnecassary overhead.

To reference Intel SDM 5.5 ("Privilege Levels"): "Privilege levels are checked
when the segment selector of a segment descriptor is loaded into a segment
register." The SDM never mentions privilege level checks during memory access,
except for loading far pointers in section 5.10 ("Pointer Validation"). Those
are actually segment selector loads and are emulated in the similarily (i.e.,
regardless to __linearize checks).

This behavior was also checked using sysexit. A data-segment whose DPL=0 was
loaded, and after sysexit (CPL=3) it is still accessible.

Therefore, all the privilege level checks in __linearize are removed.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 1317560..d9461e4 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -663,7 +663,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 	ulong la;
 	u32 lim;
 	u16 sel;
-	unsigned cpl;
 
 	la = seg_base(ctxt, addr.seg) + addr.ea;
 	*max_size = 0;
@@ -705,20 +704,6 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 		}
 		if (size > *max_size)
 			goto bad;
-		cpl = ctxt->ops->cpl(ctxt);
-		if (!fetch) {
-			/* data segment or readable code segment */
-			if (cpl > desc.dpl)
-				goto bad;
-		} else if ((desc.type & 8) && !(desc.type & 4)) {
-			/* nonconforming code segment */
-			if (cpl != desc.dpl)
-				goto bad;
-		} else if ((desc.type & 8) && (desc.type & 4)) {
-			/* conforming code segment */
-			if (cpl < desc.dpl)
-				goto bad;
-		}
 		break;
 	}
 	if (ctxt->mode != X86EMUL_MODE_PROT64)
-- 
1.9.1


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

* [PATCH 4/6] KVM: x86: Perform limit checks when assigning EIP
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
                   ` (2 preceding siblings ...)
  2014-11-19 15:43 ` [PATCH 3/6] KVM: x86: Emulator performs privilege checks on __linearize Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 15:43 ` [PATCH 5/6] KVM: x86: Non-canonical access using SS should cause #SS Nadav Amit
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

If branch (e.g., jmp, ret) causes limit violations, since the target IP >
limit, the #GP exception occurs before the branch.  In other words, the RIP
pushed on the stack should be that of the branch and not that of the target.

To do so, we can call __linearize, with new EIP, which also saves us the code
which performs the canonical address checks. On the case of assigning an EIP >=
2^32 (when switching cs.l), we also safe, as __linearize will check the new EIP
does not exceed the limit and would trigger #GP(0) otherwise.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index d9461e4..4d083fb 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -575,40 +575,6 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
 	return emulate_exception(ctxt, NM_VECTOR, 0, false);
 }
 
-static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
-			       int cs_l)
-{
-	switch (ctxt->op_bytes) {
-	case 2:
-		ctxt->_eip = (u16)dst;
-		break;
-	case 4:
-		ctxt->_eip = (u32)dst;
-		break;
-#ifdef CONFIG_X86_64
-	case 8:
-		if ((cs_l && is_noncanonical_address(dst)) ||
-		    (!cs_l && (dst >> 32) != 0))
-			return emulate_gp(ctxt, 0);
-		ctxt->_eip = dst;
-		break;
-#endif
-	default:
-		WARN(1, "unsupported eip assignment size\n");
-	}
-	return X86EMUL_CONTINUE;
-}
-
-static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
-{
-	return assign_eip_far(ctxt, dst, ctxt->mode == X86EMUL_MODE_PROT64);
-}
-
-static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
-{
-	return assign_eip_near(ctxt, ctxt->_eip + rel);
-}
-
 static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
 {
 	u16 selector;
@@ -656,7 +622,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 				       struct segmented_address addr,
 				       unsigned *max_size, unsigned size,
 				       bool write, bool fetch,
-				       ulong *linear)
+				       enum x86emul_mode mode, ulong *linear)
 {
 	struct desc_struct desc;
 	bool usable;
@@ -666,7 +632,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 
 	la = seg_base(ctxt, addr.seg) + addr.ea;
 	*max_size = 0;
-	switch (ctxt->mode) {
+	switch (mode) {
 	case X86EMUL_MODE_PROT64:
 		if (is_noncanonical_address(la))
 			return emulate_gp(ctxt, 0);
@@ -725,9 +691,55 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
 		     ulong *linear)
 {
 	unsigned max_size;
-	return __linearize(ctxt, addr, &max_size, size, write, false, linear);
+	return __linearize(ctxt, addr, &max_size, size, write, false,
+			   ctxt->mode, linear);
 }
 
+static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+			     enum x86emul_mode mode)
+{
+	ulong linear;
+	int rc;
+	unsigned max_size;
+	struct segmented_address addr = { .seg = VCPU_SREG_CS,
+					   .ea = dst };
+
+	if (ctxt->op_bytes != sizeof(unsigned long))
+		addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
+	rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear);
+	if (rc == X86EMUL_CONTINUE)
+		ctxt->_eip = addr.ea;
+	return rc;
+}
+
+static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
+{
+	return assign_eip(ctxt, dst, ctxt->mode);
+}
+
+static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
+			  const struct desc_struct *cs_desc)
+{
+	enum x86emul_mode mode = ctxt->mode;
+
+#ifdef CONFIG_X86_64
+	if (ctxt->mode >= X86EMUL_MODE_PROT32 && cs_desc->l) {
+		u64 efer = 0;
+
+		ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+		if (efer & EFER_LMA)
+			mode = X86EMUL_MODE_PROT64;
+	}
+#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);
+}
+
+static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
+{
+	return assign_eip_near(ctxt, ctxt->_eip + rel);
+}
 
 static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
 			      struct segmented_address addr,
@@ -766,7 +778,8 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
 	 * boundary check itself.  Instead, we use max_size to check
 	 * against op_size.
 	 */
-	rc = __linearize(ctxt, addr, &max_size, 0, false, true, &linear);
+	rc = __linearize(ctxt, addr, &max_size, 0, false, true, ctxt->mode,
+			 &linear);
 	if (unlikely(rc != X86EMUL_CONTINUE))
 		return rc;
 
@@ -2032,7 +2045,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
+	rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
 	if (rc != X86EMUL_CONTINUE) {
 		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
 		/* assigning eip failed; restore the old cs */
@@ -2120,7 +2133,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
 				       &new_desc);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
-	rc = assign_eip_far(ctxt, eip, new_desc.l);
+	rc = assign_eip_far(ctxt, eip, &new_desc);
 	if (rc != X86EMUL_CONTINUE) {
 		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
 		ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
@@ -3010,7 +3023,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
 	if (rc != X86EMUL_CONTINUE)
 		return X86EMUL_CONTINUE;
 
-	rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
+	rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
 	if (rc != X86EMUL_CONTINUE)
 		goto fail;
 
-- 
1.9.1


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

* [PATCH 5/6] KVM: x86: Non-canonical access using SS should cause #SS
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
                   ` (3 preceding siblings ...)
  2014-11-19 15:43 ` [PATCH 4/6] KVM: x86: Perform limit checks when assigning EIP Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 15:43 ` [PATCH 6/6] KVM: x86: Move __linearize masking of la into switch Nadav Amit
  2014-11-19 18:47 ` [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Paolo Bonzini
  6 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

When SS is used using a non-canonical address, an #SS exception is generated on
real hardware.  KVM emulator causes a #GP instead. Fix it to behave as real x86
CPU.

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 4d083fb..57dc0d7 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -635,7 +635,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 	switch (mode) {
 	case X86EMUL_MODE_PROT64:
 		if (is_noncanonical_address(la))
-			return emulate_gp(ctxt, 0);
+			goto bad;
 
 		*max_size = min_t(u64, ~0u, (1ull << 48) - la);
 		if (size > *max_size)
-- 
1.9.1


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

* [PATCH 6/6] KVM: x86: Move __linearize masking of la into switch
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
                   ` (4 preceding siblings ...)
  2014-11-19 15:43 ` [PATCH 5/6] KVM: x86: Non-canonical access using SS should cause #SS Nadav Amit
@ 2014-11-19 15:43 ` Nadav Amit
  2014-11-19 18:47 ` [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Paolo Bonzini
  6 siblings, 0 replies; 9+ messages in thread
From: Nadav Amit @ 2014-11-19 15:43 UTC (permalink / raw)
  To: pbonzini; +Cc: kvm, Nadav Amit

In __linearize there is check of the condition whether to check if masking of
the linear address is needed.  It occurs immediately after switch that
evaluates the same condition.  Merge them.

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

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 57dc0d7..19a59f3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -670,10 +670,9 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
 		}
 		if (size > *max_size)
 			goto bad;
+		la &= (u32)-1;
 		break;
 	}
-	if (ctxt->mode != X86EMUL_MODE_PROT64)
-		la &= (u32)-1;
 	if (insn_aligned(ctxt, size) && ((la & (size - 1)) != 0))
 		return emulate_gp(ctxt, 0);
 	*linear = la;
-- 
1.9.1


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

* Re: [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize
  2014-11-19 15:43 ` [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize Nadav Amit
@ 2014-11-19 17:17   ` Paolo Bonzini
  0 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-11-19 17:17 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm



On 19/11/2014 16:43, Nadav Amit wrote:
> When performing segmented-read/write in the emulator for stack operations, it
> ignores the stack size, and uses the ad_bytes as indication for the pointer
> size. As a result, a wrong address may be accessed.
> 
> To fix this behavior, we can remove the masking of address in __linearize and
> perform it beforehand.  It is already done for the operands (so currently it is
> inefficiently done twice). It is missing in two cases:
> 1. When using rip_relative
> 2. On fetch_bit_operand that changes the address.
> 
> This patch masks the address on these two occassions, and removes the masking
> from __linearize.
> 
> Note that it does not mask EIP during fetch. In protected/legacy mode code
> fetch when RIP >= 2^32 should result in #GP and not wrap-around. Since we make
> limit checks within __linearize, this is the expected behavior.

Partial revert of commit 518547b32ab4 (KVM: x86: Emulator does not
calculate address correctly, 2014-09-30).

Paolo


> Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
> ---
>  arch/x86/kvm/emulate.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 5d47714..1317560 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -665,8 +665,7 @@ static __always_inline int __linearize(struct x86_emulate_ctxt *ctxt,
>  	u16 sel;
>  	unsigned cpl;
>  
> -	la = seg_base(ctxt, addr.seg) +
> -	    (fetch || ctxt->ad_bytes == 8 ? addr.ea : (u32)addr.ea);
> +	la = seg_base(ctxt, addr.seg) + addr.ea;
>  	*max_size = 0;
>  	switch (ctxt->mode) {
>  	case X86EMUL_MODE_PROT64:
> @@ -1289,7 +1288,8 @@ static void fetch_bit_operand(struct x86_emulate_ctxt *ctxt)
>  		else
>  			sv = (s64)ctxt->src.val & (s64)mask;
>  
> -		ctxt->dst.addr.mem.ea += (sv >> 3);
> +		ctxt->dst.addr.mem.ea = address_mask(ctxt,
> +					   ctxt->dst.addr.mem.ea + (sv >> 3));
>  	}
>  
>  	/* only subword offset */
> @@ -4638,7 +4638,8 @@ done_prefixes:
>  	rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
>  
>  	if (ctxt->rip_relative)
> -		ctxt->memopp->addr.mem.ea += ctxt->_eip;
> +		ctxt->memopp->addr.mem.ea = address_mask(ctxt,
> +					ctxt->memopp->addr.mem.ea + ctxt->_eip);
>  
>  done:
>  	return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK;
> 

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

* Re: [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup
  2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
                   ` (5 preceding siblings ...)
  2014-11-19 15:43 ` [PATCH 6/6] KVM: x86: Move __linearize masking of la into switch Nadav Amit
@ 2014-11-19 18:47 ` Paolo Bonzini
  6 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-11-19 18:47 UTC (permalink / raw)
  To: Nadav Amit; +Cc: kvm



On 19/11/2014 16:43, Nadav Amit wrote:
> This patch-set fixes 4 bugs in the __linearize emulator function, and makes
> some cleanup of the function.
> 
> Patches 2 to 5 deal with separate bugs.
> 
> Patch 1 and 6 introduce minor enhancement and have no functional implications.
> The first patch reverts a patch which was written by this patch author. The
> last is a minor cleanup of __linearize.
> 
> Thanks for reviewing the patch-set.

Thanks.  I have posted two additional cleanups on top.

Paolo

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

end of thread, other threads:[~2014-11-19 18:47 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-19 15:43 [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Nadav Amit
2014-11-19 15:43 ` [PATCH 1/6] KVM: x86: Revert NoBigReal patch in the emulator Nadav Amit
2014-11-19 15:43 ` [PATCH 2/6] KVM: x86: Stack size is overridden by __linearize Nadav Amit
2014-11-19 17:17   ` Paolo Bonzini
2014-11-19 15:43 ` [PATCH 3/6] KVM: x86: Emulator performs privilege checks on __linearize Nadav Amit
2014-11-19 15:43 ` [PATCH 4/6] KVM: x86: Perform limit checks when assigning EIP Nadav Amit
2014-11-19 15:43 ` [PATCH 5/6] KVM: x86: Non-canonical access using SS should cause #SS Nadav Amit
2014-11-19 15:43 ` [PATCH 6/6] KVM: x86: Move __linearize masking of la into switch Nadav Amit
2014-11-19 18:47 ` [PATCH 0/6] KVM: x86: __linearize emulator fixes and minor cleanup Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).