From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sheng Yang Subject: [PATCH 2/2] KVM: x86 emulator: Discard CR2 in x86 emulator Date: Thu, 15 Nov 2007 15:32:20 +0800 Message-ID: <200711151532.20558.sheng.yang@intel.com> Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_EY/OHwCfGuDXUOW" To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org Errors-To: kvm-devel-bounces-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org List-Id: kvm.vger.kernel.org --Boundary-00=_EY/OHwCfGuDXUOW Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =46rom 9cd9d5cde7341d5e9de41b1070cea7a98e7d8cc9 Mon Sep 17 00:00:00 2001 =46rom: Sheng Yang Date: Thu, 15 Nov 2007 15:11:58 +0800 Subject: [PATCH 2/2] KVM: x86 emulator: Discard CR2 in x86 emulator =46or CR2 is unreliable and unavailable in many condition, this patch completely decode memory operand instead of using CR2 in x86 emulator. Signed-off-by: Sheng Yang =2D-- drivers/kvm/x86.c | 2 +- drivers/kvm/x86_emulate.c | 33 +++++++++++++++++++++------------ drivers/kvm/x86_emulate.h | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c index aa6c3d8..85a0776 100644 =2D-- a/drivers/kvm/x86.c +++ b/drivers/kvm/x86.c @@ -1293,7 +1293,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, =20 vcpu->emulate_ctxt.vcpu =3D vcpu; vcpu->emulate_ctxt.eflags =3D kvm_x86_ops->get_rflags(vcpu); =2D vcpu->emulate_ctxt.cr2 =3D cr2; + vcpu->emulate_ctxt.memop =3D 0; vcpu->emulate_ctxt.mode =3D (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM) ? X86EMUL_MODE_REAL : cs_l diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index c020010..95536a8 100644 =2D-- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -880,6 +880,8 @@ done_prefixes: break; } c->src.type =3D OP_MEM; + ctxt->memop =3D insn_fetch(u32, c->src.bytes, c->eip); + c->eip -=3D c->src.bytes; /* keep the page fault ip */ break; case SrcImm: c->src.type =3D OP_IMM; @@ -918,14 +920,18 @@ done_prefixes: c->twobyte && (c->b =3D=3D 0xb6 || c->b =3D=3D 0xb7)); break; case DstMem: + c->dst.bytes =3D (c->d & ByteOp) ? 1 : c->op_bytes; /* * For instructions with a ModR/M byte, switch to register * access if Mod =3D 3. */ =2D if ((c->d & ModRM) && c->modrm_mod =3D=3D 3) + if ((c->d & ModRM) && c->modrm_mod =3D=3D 3) { c->dst.type =3D OP_REG; =2D else =2D c->dst.type =3D OP_MEM; + break; + } + c->dst.type =3D OP_MEM; + ctxt->memop =3D insn_fetch(u32, c->dst.bytes, c->eip); + c->eip -=3D c->dst.bytes; /* keep the page fault ip */ break; } =20 @@ -1091,13 +1097,13 @@ static inline int emulate_grp45(struct=20 x86_emulate_ctxt *ctxt, =20 static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, =2D unsigned long cr2) + unsigned long memop) { struct decode_cache *c =3D &ctxt->decode; u64 old, new; int rc; =20 =2D rc =3D ops->read_emulated(cr2, &old, 8, ctxt->vcpu); + rc =3D ops->read_emulated(memop, &old, 8, ctxt->vcpu); if (rc !=3D 0) return rc; =20 @@ -1112,7 +1118,7 @@ static inline int emulate_grp9(struct x86_emulate_ctx= t=20 *ctxt, new =3D ((u64)c->regs[VCPU_REGS_RCX] << 32) | (u32) c->regs[VCPU_REGS_RBX]; =20 =2D rc =3D ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu); + rc =3D ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); if (rc !=3D 0) return rc; ctxt->eflags |=3D EFLG_ZF; @@ -1175,7 +1181,7 @@ static inline int writeback(struct x86_emulate_ctxt=20 *ctxt, int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *op= s) { =2D unsigned long cr2 =3D ctxt->cr2; + unsigned long memop; u64 msr_data; unsigned long saved_eip; struct decode_cache *c =3D &ctxt->decode; @@ -1190,10 +1196,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, str= uct=20 x86_emulate_ops *ops) saved_eip =3D c->eip; =20 if (((c->d & ModRM) && (c->modrm_mod !=3D 3)) || (c->d & MemAbs)) =2D cr2 =3D c->modrm_ea; + memop =3D c->modrm_ea; + else if ((c->d & DstMask) !=3D ImplicitOps) + memop =3D ctxt->memop; + else memop =3D 0; =20 if (c->src.type =3D=3D OP_MEM) { =2D c->src.ptr =3D (unsigned long *)cr2; + c->src.ptr =3D (unsigned long *)memop; c->src.val =3D 0; rc =3D ops->read_emulated((unsigned long)c->src.ptr, &c->src.val, @@ -1209,7 +1218,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struc= t=20 x86_emulate_ops *ops) =20 =20 if (c->dst.type =3D=3D OP_MEM) { =2D c->dst.ptr =3D (unsigned long *)cr2; + c->dst.ptr =3D (unsigned long *)memop; c->dst.bytes =3D (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.val =3D 0; if (c->d & BitOp) { @@ -1648,7 +1657,7 @@ twobyte_insn: &ctxt->eflags); break; case 7: /* invlpg*/ =2D emulate_invlpg(ctxt->vcpu, cr2); + emulate_invlpg(ctxt->vcpu, memop); break; default: goto cannot_emulate; @@ -1819,7 +1828,7 @@ twobyte_special_insn: break; } case 0xc7: /* Grp9 (cmpxchg8b) */ =2D rc =3D emulate_grp9(ctxt, ops, cr2); + rc =3D emulate_grp9(ctxt, ops, memop); if (rc !=3D 0) goto done; break; diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h index e34868b..5aacc76 100644 =2D-- a/drivers/kvm/x86_emulate.h +++ b/drivers/kvm/x86_emulate.h @@ -149,7 +149,7 @@ struct x86_emulate_ctxt { =20 /* Linear faulting address (if emulating a page-faulting instruction). */ unsigned long eflags; =2D unsigned long cr2; + unsigned long memop; =20 /* Emulated execution mode, represented by an X86EMUL_MODE value. */ int mode; =2D-=20 1.5.2 --Boundary-00=_EY/OHwCfGuDXUOW Content-Type: text/x-diff; charset="utf-8"; name="0002-KVM-x86-emulator-Discard-CR2-in-x86-emulator.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-KVM-x86-emulator-Discard-CR2-in-x86-emulator.patch" =46rom 9cd9d5cde7341d5e9de41b1070cea7a98e7d8cc9 Mon Sep 17 00:00:00 2001 =46rom: Sheng Yang Date: Thu, 15 Nov 2007 15:11:58 +0800 Subject: [PATCH 2/2] KVM: x86 emulator: Discard CR2 in x86 emulator =46or CR2 is unreliable and unavailable in many condition, this patch completely decode memory operand instead of using CR2 in x86 emulator. Signed-off-by: Sheng Yang =2D-- drivers/kvm/x86.c | 2 +- drivers/kvm/x86_emulate.c | 33 +++++++++++++++++++++------------ drivers/kvm/x86_emulate.h | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c index aa6c3d8..85a0776 100644 =2D-- a/drivers/kvm/x86.c +++ b/drivers/kvm/x86.c @@ -1293,7 +1293,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu, =20 vcpu->emulate_ctxt.vcpu =3D vcpu; vcpu->emulate_ctxt.eflags =3D kvm_x86_ops->get_rflags(vcpu); =2D vcpu->emulate_ctxt.cr2 =3D cr2; + vcpu->emulate_ctxt.memop =3D 0; vcpu->emulate_ctxt.mode =3D (vcpu->emulate_ctxt.eflags & X86_EFLAGS_VM) ? X86EMUL_MODE_REAL : cs_l diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index c020010..95536a8 100644 =2D-- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c @@ -880,6 +880,8 @@ done_prefixes: break; } c->src.type =3D OP_MEM; + ctxt->memop =3D insn_fetch(u32, c->src.bytes, c->eip); + c->eip -=3D c->src.bytes; /* keep the page fault ip */ break; case SrcImm: c->src.type =3D OP_IMM; @@ -918,14 +920,18 @@ done_prefixes: c->twobyte && (c->b =3D=3D 0xb6 || c->b =3D=3D 0xb7)); break; case DstMem: + c->dst.bytes =3D (c->d & ByteOp) ? 1 : c->op_bytes; /* * For instructions with a ModR/M byte, switch to register * access if Mod =3D 3. */ =2D if ((c->d & ModRM) && c->modrm_mod =3D=3D 3) + if ((c->d & ModRM) && c->modrm_mod =3D=3D 3) { c->dst.type =3D OP_REG; =2D else =2D c->dst.type =3D OP_MEM; + break; + } + c->dst.type =3D OP_MEM; + ctxt->memop =3D insn_fetch(u32, c->dst.bytes, c->eip); + c->eip -=3D c->dst.bytes; /* keep the page fault ip */ break; } =20 @@ -1091,13 +1097,13 @@ static inline int emulate_grp45(struct x86_emulate_= ctxt *ctxt, =20 static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, =2D unsigned long cr2) + unsigned long memop) { struct decode_cache *c =3D &ctxt->decode; u64 old, new; int rc; =20 =2D rc =3D ops->read_emulated(cr2, &old, 8, ctxt->vcpu); + rc =3D ops->read_emulated(memop, &old, 8, ctxt->vcpu); if (rc !=3D 0) return rc; =20 @@ -1112,7 +1118,7 @@ static inline int emulate_grp9(struct x86_emulate_ctx= t *ctxt, new =3D ((u64)c->regs[VCPU_REGS_RCX] << 32) | (u32) c->regs[VCPU_REGS_RBX]; =20 =2D rc =3D ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt->vcpu); + rc =3D ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu); if (rc !=3D 0) return rc; ctxt->eflags |=3D EFLG_ZF; @@ -1175,7 +1181,7 @@ static inline int writeback(struct x86_emulate_ctxt *= ctxt, int x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *op= s) { =2D unsigned long cr2 =3D ctxt->cr2; + unsigned long memop; u64 msr_data; unsigned long saved_eip; struct decode_cache *c =3D &ctxt->decode; @@ -1190,10 +1196,13 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, str= uct x86_emulate_ops *ops) saved_eip =3D c->eip; =20 if (((c->d & ModRM) && (c->modrm_mod !=3D 3)) || (c->d & MemAbs)) =2D cr2 =3D c->modrm_ea; + memop =3D c->modrm_ea; + else if ((c->d & DstMask) !=3D ImplicitOps) + memop =3D ctxt->memop; + else memop =3D 0; =20 if (c->src.type =3D=3D OP_MEM) { =2D c->src.ptr =3D (unsigned long *)cr2; + c->src.ptr =3D (unsigned long *)memop; c->src.val =3D 0; rc =3D ops->read_emulated((unsigned long)c->src.ptr, &c->src.val, @@ -1209,7 +1218,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struc= t x86_emulate_ops *ops) =20 =20 if (c->dst.type =3D=3D OP_MEM) { =2D c->dst.ptr =3D (unsigned long *)cr2; + c->dst.ptr =3D (unsigned long *)memop; c->dst.bytes =3D (c->d & ByteOp) ? 1 : c->op_bytes; c->dst.val =3D 0; if (c->d & BitOp) { @@ -1648,7 +1657,7 @@ twobyte_insn: &ctxt->eflags); break; case 7: /* invlpg*/ =2D emulate_invlpg(ctxt->vcpu, cr2); + emulate_invlpg(ctxt->vcpu, memop); break; default: goto cannot_emulate; @@ -1819,7 +1828,7 @@ twobyte_special_insn: break; } case 0xc7: /* Grp9 (cmpxchg8b) */ =2D rc =3D emulate_grp9(ctxt, ops, cr2); + rc =3D emulate_grp9(ctxt, ops, memop); if (rc !=3D 0) goto done; break; diff --git a/drivers/kvm/x86_emulate.h b/drivers/kvm/x86_emulate.h index e34868b..5aacc76 100644 =2D-- a/drivers/kvm/x86_emulate.h +++ b/drivers/kvm/x86_emulate.h @@ -149,7 +149,7 @@ struct x86_emulate_ctxt { =20 /* Linear faulting address (if emulating a page-faulting instruction). */ unsigned long eflags; =2D unsigned long cr2; + unsigned long memop; =20 /* Emulated execution mode, represented by an X86EMUL_MODE value. */ int mode; =2D-=20 1.5.2 --Boundary-00=_EY/OHwCfGuDXUOW Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ --Boundary-00=_EY/OHwCfGuDXUOW Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ kvm-devel mailing list kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/kvm-devel --Boundary-00=_EY/OHwCfGuDXUOW--