public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] KVM: Cleanups: X86EMUL_* related.
@ 2010-01-28 13:51 Takuya Yoshikawa
  2010-01-28 13:54 ` [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std Takuya Yoshikawa
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 13:51 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

Hi,

Sorry for a bit noisy cleanups. But during this
work, we noticed some buggy return value checks
and determined to send this work as a patch series.

Thanks,
 Takuya Yoshikawa

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

* [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std
  2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
@ 2010-01-28 13:54 ` Takuya Yoshikawa
  2010-01-29 20:46   ` Marcelo Tosatti
  2010-01-28 13:56 ` [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or Takuya Yoshikawa
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 13:54 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

read_std is one of the x86_emulate_ops. This patch fix the
return value check to use the proper macro.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/emulate.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 645b245..b124578 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -607,7 +607,7 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
 	if (linear < fc->start || linear >= fc->end) {
 		size = min(15UL, PAGE_SIZE - offset_in_page(linear));
 		rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
-		if (rc)
+		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		fc->start = linear;
 		fc->end = linear + size;
@@ -662,7 +662,7 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt,
 	*address = 0;
 	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
 			   ctxt->vcpu);
-	if (rc)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
 			   ctxt->vcpu);
-- 
1.6.3.3


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

* [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or ...
  2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
  2010-01-28 13:54 ` [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std Takuya Yoshikawa
@ 2010-01-28 13:56 ` Takuya Yoshikawa
  2010-01-29 21:18   ` Marcelo Tosatti
  2010-01-28 13:59 ` [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values Takuya Yoshikawa
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 13:56 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

These functions returns X86EMUL_* or 0 or 1 or ...
This patch fix the conflicts between these values and make
them return one of X86EMUL_* values.

NOTE: In these functions, directly returning the ret value
  from the kvm_load_segment_descriptor should have been fixed.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/emulate.c |   44 +++++++++++++++++++++-----------------------
 1 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b124578..9953f5b 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -613,14 +613,14 @@ static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
 		fc->end = linear + size;
 	}
 	*dest = fc->data[linear - fc->start];
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
 			 struct x86_emulate_ops *ops,
 			 unsigned long eip, void *dest, unsigned size)
 {
-	int rc = 0;
+	int rc;
 
 	/* x86 instructions are limited to 15 bytes. */
 	if (eip + size - ctxt->decode.eip_orig > 15)
@@ -628,10 +628,10 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
 	eip += ctxt->cs_base;
 	while (size--) {
 		rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
-		if (rc)
+		if (rc != X86EMUL_CONTINUE)
 			return rc;
 	}
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 /*
@@ -742,7 +742,7 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
 	struct decode_cache *c = &ctxt->decode;
 	u8 sib;
 	int index_reg = 0, base_reg = 0, scale;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 
 	if (c->rex_prefix) {
 		c->modrm_reg = (c->rex_prefix & 4) << 1;	/* REX.R */
@@ -855,7 +855,7 @@ static int decode_abs(struct x86_emulate_ctxt *ctxt,
 		      struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 
 	switch (c->ad_bytes) {
 	case 2:
@@ -876,7 +876,7 @@ int
 x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 	int mode = ctxt->mode;
 	int def_op_bytes, def_ad_bytes, group;
 
@@ -1222,10 +1222,11 @@ static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
 	int rc;
 
 	rc = emulate_pop(ctxt, ops, &selector, c->op_bytes);
-	if (rc != 0)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
+	if (kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg))
+		return X86EMUL_UNHANDLEABLE;
 	return rc;
 }
 
@@ -1248,7 +1249,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt,
 			struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 	int reg = VCPU_REGS_RDI;
 
 	while (reg >= VCPU_REGS_RAX) {
@@ -1259,7 +1260,7 @@ static int emulate_popa(struct x86_emulate_ctxt *ctxt,
 		}
 
 		rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			break;
 		--reg;
 	}
@@ -1270,12 +1271,8 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
 				struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	int rc;
 
-	rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
-	if (rc != 0)
-		return rc;
-	return 0;
+	return emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
 }
 
 static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
@@ -1311,7 +1308,7 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
 			       struct x86_emulate_ops *ops)
 {
 	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 
 	switch (c->modrm_reg) {
 	case 0 ... 1:	/* test */
@@ -1358,7 +1355,7 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
 		emulate_push(ctxt);
 		break;
 	}
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
@@ -1389,7 +1386,7 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
 			return rc;
 		ctxt->eflags |= EFLG_ZF;
 	}
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
@@ -1400,14 +1397,15 @@ static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
 	unsigned long cs;
 
 	rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
-	if (rc)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	if (c->op_bytes == 4)
 		c->eip = (u32)c->eip;
 	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
-	if (rc)
+	if (rc != X86EMUL_CONTINUE)
 		return rc;
-	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
+	if (kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS))
+		return X86EMUL_UNHANDLEABLE;
 	return rc;
 }
 
@@ -1460,7 +1458,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt,
 	default:
 		break;
 	}
-	return 0;
+	return X86EMUL_CONTINUE;
 }
 
 static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
-- 
1.6.3.3


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

* [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values
  2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
  2010-01-28 13:54 ` [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std Takuya Yoshikawa
  2010-01-28 13:56 ` [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or Takuya Yoshikawa
@ 2010-01-28 13:59 ` Takuya Yoshikawa
  2010-01-29 21:21   ` Marcelo Tosatti
  2010-01-28 14:01 ` [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return " Takuya Yoshikawa
  2010-01-28 14:03 ` [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c Takuya Yoshikawa
  4 siblings, 1 reply; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 13:59 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

This patch differentiate the X86EMUL_* values returned from
X86EMUL_* type functions.

Note: During this work, we noticed some buggy return value
  checks in x86_emulate_insn(). See FIXME in this patch.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/emulate.c |   73 +++++++++++++++++++++++++++++-------------------
 1 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 9953f5b..d49e9de 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1693,7 +1693,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	struct decode_cache *c = &ctxt->decode;
 	unsigned int port;
 	int io_dir_in;
-	int rc = 0;
+	int rc = X86EMUL_CONTINUE;
 
 	ctxt->interruptibility = 0;
 
@@ -1791,7 +1791,7 @@ special_insn:
 		break;
 	case 0x07:		/* pop es */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x08 ... 0x0d:
@@ -1810,7 +1810,7 @@ special_insn:
 		break;
 	case 0x17:		/* pop ss */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x18 ... 0x1d:
@@ -1822,7 +1822,7 @@ special_insn:
 		break;
 	case 0x1f:		/* pop ds */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x20 ... 0x25:
@@ -1853,7 +1853,7 @@ special_insn:
 	case 0x58 ... 0x5f: /* pop reg */
 	pop_instruction:
 		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x60:	/* pusha */
@@ -1861,7 +1861,7 @@ special_insn:
 		break;
 	case 0x61:	/* popa */
 		rc = emulate_popa(ctxt, ops);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x63:		/* movsxd */
@@ -2002,7 +2002,7 @@ special_insn:
 	}
 	case 0x8f:		/* pop (sole member of Grp1a) */
 		rc = emulate_grp1a(ctxt, ops);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0x90: /* nop / xchg r8,rax */
@@ -2135,7 +2135,7 @@ special_insn:
 		break;
 	case 0xcb:		/* ret far */
 		rc = emulate_ret_far(ctxt, ops);
-		if (rc)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0xd0 ... 0xd1:	/* Grp2 */
@@ -2205,7 +2205,7 @@ special_insn:
 		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
 		rc = emulate_grp3(ctxt, ops);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0xf8: /* clc */
@@ -2231,14 +2231,14 @@ special_insn:
 		break;
 	case 0xfe ... 0xff:	/* Grp4/Grp5 */
 		rc = emulate_grp45(ctxt, ops);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	}
 
 writeback:
 	rc = writeback(ctxt, ops);
-	if (rc != 0)
+	if (rc != X86EMUL_CONTINUE)
 		goto done;
 
 	/* Commit shadow register state. */
@@ -2263,8 +2263,18 @@ twobyte_insn:
 			if (c->modrm_mod != 3 || c->modrm_rm != 1)
 				goto cannot_emulate;
 
-			rc = kvm_fix_hypercall(ctxt->vcpu);
-			if (rc)
+			/* FIXME:
+			 * kvm_fix_hypercall() calls emulator_write_emulated()
+			 * and if the return value is not X86EMUL_CONTINUE then
+			 * returns -EFAULT, otherwise returns X86EMUL_CONTINUE.
+			 *
+			 * To handle the former case, original code just did
+			 * goto done with rc = -EFAULT and passed the
+			 * if (X86EMUL_UNHANDLEABLE) check.
+			 * Instead of this, we just set rc to X86EMUL_CONTINUE.
+			 */
+			rc = X86EMUL_CONTINUE;
+			if (kvm_fix_hypercall(ctxt->vcpu))
 				goto done;
 
 			/* Let the processor re-execute the fixed hypercall */
@@ -2275,7 +2285,7 @@ twobyte_insn:
 		case 2: /* lgdt */
 			rc = read_descriptor(ctxt, ops, c->src.ptr,
 					     &size, &address, c->op_bytes);
-			if (rc)
+			if (rc != X86EMUL_CONTINUE)
 				goto done;
 			realmode_lgdt(ctxt->vcpu, size, address);
 			/* Disable writeback. */
@@ -2285,8 +2295,9 @@ twobyte_insn:
 			if (c->modrm_mod == 3) {
 				switch (c->modrm_rm) {
 				case 1:
-					rc = kvm_fix_hypercall(ctxt->vcpu);
-					if (rc)
+					/* FIXME: See above */
+					rc = X86EMUL_CONTINUE;
+					if (kvm_fix_hypercall(ctxt->vcpu))
 						goto done;
 					break;
 				default:
@@ -2296,7 +2307,7 @@ twobyte_insn:
 				rc = read_descriptor(ctxt, ops, c->src.ptr,
 						     &size, &address,
 						     c->op_bytes);
-				if (rc)
+				if (rc != X86EMUL_CONTINUE)
 					goto done;
 				realmode_lidt(ctxt->vcpu, size, address);
 			}
@@ -2347,9 +2358,12 @@ twobyte_insn:
 	case 0x21: /* mov from dr to reg */
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
-		rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
-		if (rc)
+		if (emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]))
 			goto cannot_emulate;
+		/* FIXME: Next line is just for ensuring to pass
+		 * the if (rc != X86EMUL_UNHANDLEABLE) test.
+		 */
+		rc = X86EMUL_CONTINUE;
 		c->dst.type = OP_NONE;	/* no writeback */
 		break;
 	case 0x22: /* mov reg, cr */
@@ -2362,18 +2376,19 @@ twobyte_insn:
 	case 0x23: /* mov from reg to dr */
 		if (c->modrm_mod != 3)
 			goto cannot_emulate;
-		rc = emulator_set_dr(ctxt, c->modrm_reg,
-				     c->regs[c->modrm_rm]);
-		if (rc)
+		if (emulator_set_dr(ctxt, c->modrm_reg, c->regs[c->modrm_rm]))
 			goto cannot_emulate;
+		/* FIXME: Next line is just for ensuring to pass
+		 * the if (rc != X86EMUL_UNHANDLEABLE) test.
+		 */
+		rc = X86EMUL_CONTINUE;
 		c->dst.type = OP_NONE;	/* no writeback */
 		break;
 	case 0x30:
 		/* wrmsr */
 		msr_data = (u32)c->regs[VCPU_REGS_RAX]
 			| ((u64)c->regs[VCPU_REGS_RDX] << 32);
-		rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
-		if (rc) {
+		if (kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) {
 			kvm_inject_gp(ctxt->vcpu, 0);
 			c->eip = kvm_rip_read(ctxt->vcpu);
 		}
@@ -2382,8 +2397,8 @@ twobyte_insn:
 		break;
 	case 0x32:
 		/* rdmsr */
-		rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
-		if (rc) {
+		if (kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX],
+				&msr_data)) {
 			kvm_inject_gp(ctxt->vcpu, 0);
 			c->eip = kvm_rip_read(ctxt->vcpu);
 		} else {
@@ -2420,7 +2435,7 @@ twobyte_insn:
 		break;
 	case 0xa1:	 /* pop fs */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0xa3:
@@ -2439,7 +2454,7 @@ twobyte_insn:
 		break;
 	case 0xa9:	/* pop gs */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		break;
 	case 0xab:
@@ -2512,7 +2527,7 @@ twobyte_insn:
 		break;
 	case 0xc7:		/* Grp9 (cmpxchg8b) */
 		rc = emulate_grp9(ctxt, ops, memop);
-		if (rc != 0)
+		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		c->dst.type = OP_NONE;
 		break;
-- 
1.6.3.3


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

* [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return X86EMUL_* values
  2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
                   ` (2 preceding siblings ...)
  2010-01-28 13:59 ` [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values Takuya Yoshikawa
@ 2010-01-28 14:01 ` Takuya Yoshikawa
  2010-01-29 21:30   ` Marcelo Tosatti
  2010-01-28 14:03 ` [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c Takuya Yoshikawa
  4 siblings, 1 reply; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 14:01 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

These two functions should return X86EMUL_* values.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/x86.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ac8672f..78b8ddb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4663,7 +4663,7 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 
 	if (dtable.limit < index * 8 + 7) {
 		kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
-		return 1;
+		return X86EMUL_UNHANDLEABLE;
 	}
 	return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
 }
@@ -4678,7 +4678,7 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 	get_segment_descriptor_dtable(vcpu, selector, &dtable);
 
 	if (dtable.limit < index * 8 + 7)
-		return 1;
+		return X86EMUL_UNHANDLEABLE;
 	return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
 }
 
-- 
1.6.3.3


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

* [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c
  2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
                   ` (3 preceding siblings ...)
  2010-01-28 14:01 ` [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return " Takuya Yoshikawa
@ 2010-01-28 14:03 ` Takuya Yoshikawa
  2010-01-29 21:39   ` Marcelo Tosatti
  4 siblings, 1 reply; 11+ messages in thread
From: Takuya Yoshikawa @ 2010-01-28 14:03 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm

pio_copy_data() and load|save_guest_segment_descriptor()
return X86EMUL_* values. Mixing up these values with 0, 1, ...
may produce unpridictable bugs.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
---
 arch/x86/kvm/x86.c |   27 +++++++++++++++------------
 1 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 78b8ddb..67f8231 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3454,7 +3454,6 @@ int complete_pio(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pio_request *io = &vcpu->arch.pio;
 	long delta;
-	int r;
 	unsigned long val;
 
 	if (!io->string) {
@@ -3465,9 +3464,9 @@ int complete_pio(struct kvm_vcpu *vcpu)
 		}
 	} else {
 		if (io->in) {
-			r = pio_copy_data(vcpu);
-			if (r)
-				return r;
+			int ret = pio_copy_data(vcpu);
+			if (ret != X86EMUL_CONTINUE)
+				return 1;
 		}
 
 		delta = 1;
@@ -3567,7 +3566,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
 		  gva_t address, int rep, unsigned port)
 {
 	unsigned now, in_page;
-	int ret = 0;
 
 	vcpu->run->exit_reason = KVM_EXIT_IO;
 	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
@@ -3613,20 +3611,22 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
 
 	if (!vcpu->arch.pio.in) {
 		/* string PIO write */
-		ret = pio_copy_data(vcpu);
+		int ret = pio_copy_data(vcpu);
 		if (ret == X86EMUL_PROPAGATE_FAULT) {
 			kvm_inject_gp(vcpu, 0);
 			return 1;
 		}
-		if (ret == 0 && !pio_string_write(vcpu)) {
+		if (ret == X86EMUL_UNHANDLEABLE)
+			return 1;
+		if (ret == X86EMUL_CONTINUE && !pio_string_write(vcpu)) {
 			complete_pio(vcpu);
 			if (vcpu->arch.pio.count == 0)
-				ret = 1;
+				return 1;
 		}
 	}
 	/* no string PIO read support yet */
 
-	return ret;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
 
@@ -4743,7 +4743,8 @@ int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 	if (is_vm86_segment(vcpu, seg) || !is_protmode(vcpu))
 		return kvm_load_realmode_segment(vcpu, selector, seg);
 
-	if (load_guest_segment_descriptor(vcpu, selector, &seg_desc))
+	if (load_guest_segment_descriptor(vcpu, selector, &seg_desc)
+		!= X86EMUL_CONTINUE)
 		return 1;
 	seg_desct_to_kvm_desct(&seg_desc, selector, &kvm_seg);
 
@@ -4971,10 +4972,12 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
 	/* FIXME: Handle errors. Failure to read either TSS or their
 	 * descriptors should generate a pagefault.
 	 */
-	if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc))
+	if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc)
+		!= X86EMUL_CONTINUE)
 		goto out;
 
-	if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc))
+	if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc)
+		!= X86EMUL_CONTINUE)
 		goto out;
 
 	if (reason != TASK_SWITCH_IRET) {
-- 
1.6.3.3


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

* Re: [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std
  2010-01-28 13:54 ` [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std Takuya Yoshikawa
@ 2010-01-29 20:46   ` Marcelo Tosatti
  0 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-01-29 20:46 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, kvm

On Thu, Jan 28, 2010 at 10:54:40PM +0900, Takuya Yoshikawa wrote:
> read_std is one of the x86_emulate_ops. This patch fix the
> return value check to use the proper macro.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>

Applied, thanks.



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

* Re: [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or ...
  2010-01-28 13:56 ` [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or Takuya Yoshikawa
@ 2010-01-29 21:18   ` Marcelo Tosatti
  0 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-01-29 21:18 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, kvm

On Thu, Jan 28, 2010 at 10:56:52PM +0900, Takuya Yoshikawa wrote:
> These functions returns X86EMUL_* or 0 or 1 or ...
> This patch fix the conflicts between these values and make
> them return one of X86EMUL_* values.
> 
> NOTE: In these functions, directly returning the ret value
>   from the kvm_load_segment_descriptor should have been fixed.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> ---
>  arch/x86/kvm/emulate.c |   44 +++++++++++++++++++++-----------------------
>  1 files changed, 21 insertions(+), 23 deletions(-)
> 
> -	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg);
> +	if (kvm_load_segment_descriptor(ctxt->vcpu, (u16)selector, 1, seg))
> +		return X86EMUL_UNHANDLEABLE;

Its better to propagate the return value from
kvm_load_segment_descriptor (which can be updated to return accurate
codes, eg PROPAGATE_FAULT if exception has been raised).

Also please send logic changes separately from macro replacement.


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

* Re: [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values
  2010-01-28 13:59 ` [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values Takuya Yoshikawa
@ 2010-01-29 21:21   ` Marcelo Tosatti
  0 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-01-29 21:21 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, kvm

On Thu, Jan 28, 2010 at 10:59:29PM +0900, Takuya Yoshikawa wrote:
> This patch differentiate the X86EMUL_* values returned from
> X86EMUL_* type functions.
> 
> Note: During this work, we noticed some buggy return value
>   checks in x86_emulate_insn(). See FIXME in this patch.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> ---
>  arch/x86/kvm/emulate.c |   73 +++++++++++++++++++++++++++++-------------------
>  1 files changed, 44 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 9953f5b..d49e9de 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
>  
>  	/* Commit shadow register state. */
> @@ -2263,8 +2263,18 @@ twobyte_insn:
>  			if (c->modrm_mod != 3 || c->modrm_rm != 1)
>  				goto cannot_emulate;
>  
> -			rc = kvm_fix_hypercall(ctxt->vcpu);
> -			if (rc)
> +			/* FIXME:
> +			 * kvm_fix_hypercall() calls emulator_write_emulated()
> +			 * and if the return value is not X86EMUL_CONTINUE then
> +			 * returns -EFAULT, otherwise returns X86EMUL_CONTINUE.
> +			 *
> +			 * To handle the former case, original code just did
> +			 * goto done with rc = -EFAULT and passed the
> +			 * if (X86EMUL_UNHANDLEABLE) check.
> +			 * Instead of this, we just set rc to X86EMUL_CONTINUE.
> +			 */
> +			rc = X86EMUL_CONTINUE;
> +			if (kvm_fix_hypercall(ctxt->vcpu))
>  				goto done;

Should fix kvm_fix_hypercall to return X86EMUL_ codes, and send macro
updates separately from logic changes.


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

* Re: [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return X86EMUL_* values
  2010-01-28 14:01 ` [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return " Takuya Yoshikawa
@ 2010-01-29 21:30   ` Marcelo Tosatti
  0 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-01-29 21:30 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, kvm

On Thu, Jan 28, 2010 at 11:01:30PM +0900, Takuya Yoshikawa wrote:
> These two functions should return X86EMUL_* values.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> ---
>  arch/x86/kvm/x86.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)

I think it would be best to improve the return values here (as 
documented in kvm_emulate.h). 

> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ac8672f..78b8ddb 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -4663,7 +4663,7 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
>  
>  	if (dtable.limit < index * 8 + 7) {
>  		kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
> -		return 1;
> +		return X86EMUL_UNHANDLEABLE;
>  	}

This should be X86EMUL_PROPAGATE_FAULT so the #GP is injected (and error
not propagated to caller).

>  	return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
>  }
> @@ -4678,7 +4678,7 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
>  	get_segment_descriptor_dtable(vcpu, selector, &dtable);
>  
>  	if (dtable.limit < index * 8 + 7)
> -		return 1;
> +		return X86EMUL_UNHANDLEABLE;
>  	return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
>  }


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

* Re: [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c
  2010-01-28 14:03 ` [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c Takuya Yoshikawa
@ 2010-01-29 21:39   ` Marcelo Tosatti
  0 siblings, 0 replies; 11+ messages in thread
From: Marcelo Tosatti @ 2010-01-29 21:39 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, kvm

On Thu, Jan 28, 2010 at 11:03:34PM +0900, Takuya Yoshikawa wrote:
> pio_copy_data() and load|save_guest_segment_descriptor()
> return X86EMUL_* values. Mixing up these values with 0, 1, ...
> may produce unpridictable bugs.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> ---
>  arch/x86/kvm/x86.c |   27 +++++++++++++++------------
>  1 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 78b8ddb..67f8231 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3454,7 +3454,6 @@ int complete_pio(struct kvm_vcpu *vcpu)
>  {
>  	struct kvm_pio_request *io = &vcpu->arch.pio;
>  	long delta;
> -	int r;
>  	unsigned long val;
>  
>  	if (!io->string) {
> @@ -3465,9 +3464,9 @@ int complete_pio(struct kvm_vcpu *vcpu)
>  		}
>  	} else {
>  		if (io->in) {
> -			r = pio_copy_data(vcpu);
> -			if (r)
> -				return r;
> +			int ret = pio_copy_data(vcpu);
> +			if (ret != X86EMUL_CONTINUE)
> +				return 1;
>  		}
>  
>  		delta = 1;
> @@ -3567,7 +3566,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
>  		  gva_t address, int rep, unsigned port)
>  {
>  	unsigned now, in_page;
> -	int ret = 0;
>  
>  	vcpu->run->exit_reason = KVM_EXIT_IO;
>  	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
> @@ -3613,20 +3611,22 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, int in,
>  
>  	if (!vcpu->arch.pio.in) {
>  		/* string PIO write */
> -		ret = pio_copy_data(vcpu);
> +		int ret = pio_copy_data(vcpu);
>  		if (ret == X86EMUL_PROPAGATE_FAULT) {
>  			kvm_inject_gp(vcpu, 0);
>  			return 1;
>  		}
> -		if (ret == 0 && !pio_string_write(vcpu)) {
> +		if (ret == X86EMUL_UNHANDLEABLE)
> +			return 1;
> +		if (ret == X86EMUL_CONTINUE && !pio_string_write(vcpu)) {
>  			complete_pio(vcpu);
>  			if (vcpu->arch.pio.count == 0)
> -				ret = 1;
> +				return 1;
>  		}
>  	}
>  	/* no string PIO read support yet */
>  
> -	return ret;
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);

This function is used by the emulator, and as such should return
X86_EMUL values?

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

end of thread, other threads:[~2010-01-29 21:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-28 13:51 [PATCH 0/5] KVM: Cleanups: X86EMUL_* related Takuya Yoshikawa
2010-01-28 13:54 ` [PATCH 1/5] KVM: Use X86EMUL_* to check the return value from read_std Takuya Yoshikawa
2010-01-29 20:46   ` Marcelo Tosatti
2010-01-28 13:56 ` [PATCH 2/5] KVM: These functions should return X86EMUL_* not 0 or 1 or Takuya Yoshikawa
2010-01-29 21:18   ` Marcelo Tosatti
2010-01-28 13:59 ` [PATCH 3/5] KVM: Restrict rc values in x86_emulate_insn to X86EMUL_* values Takuya Yoshikawa
2010-01-29 21:21   ` Marcelo Tosatti
2010-01-28 14:01 ` [PATCH 4/5] KVM: load|save_guest_segment_descriptor() should return " Takuya Yoshikawa
2010-01-29 21:30   ` Marcelo Tosatti
2010-01-28 14:03 ` [PATCH 5/5] KVM: Fix the usage of X86EMUL_* values in x86.c Takuya Yoshikawa
2010-01-29 21:39   ` Marcelo Tosatti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox