From 77beab01a46587dd199e2dcfeee5e5727aac9fc6 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 12 Jun 2012 20:03:23 +0300 Subject: [PATCH] --- yaml --- r: 315887 b: refs/heads/master c: 612e89f01569f562dfa76cd5b76310a42b34a214 h: refs/heads/master i: 315885: 889e2ee9ccafd63c35d86a6af9e983cbd1cd275b 315883: cad436926c92fc42caa24a2e6cfcc25f4e9d2bc1 315879: 251f772780d72ae71e50bf7133eb5c9fa9f87c0e 315871: d9d2e013929396e72f2acbb8c46fc4b378914491 v: v3 --- [refs] | 2 +- trunk/arch/x86/kvm/emulate.c | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index a461ec19eb69..b482ed6afbd8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 51ddff50cbd77568fe40e17a966b3a2ef1231b36 +refs/heads/master: 612e89f01569f562dfa76cd5b76310a42b34a214 diff --git a/trunk/arch/x86/kvm/emulate.c b/trunk/arch/x86/kvm/emulate.c index acc647d63701..b4b326ebc835 100644 --- a/trunk/arch/x86/kvm/emulate.c +++ b/trunk/arch/x86/kvm/emulate.c @@ -454,6 +454,11 @@ static ulong stack_mask(struct x86_emulate_ctxt *ctxt) return ~0U >> ((ss.d ^ 1) * 16); /* d=0: 0xffff; d=1: 0xffffffff */ } +static int stack_size(struct x86_emulate_ctxt *ctxt) +{ + return (__fls(stack_mask(ctxt)) + 1) >> 3; +} + /* Access/update address held in a register, based on addressing mode. */ static inline unsigned long address_mask(struct x86_emulate_ctxt *ctxt, unsigned long reg) @@ -1592,6 +1597,26 @@ static int em_popf(struct x86_emulate_ctxt *ctxt) return emulate_popf(ctxt, &ctxt->dst.val, ctxt->op_bytes); } +static int em_enter(struct x86_emulate_ctxt *ctxt) +{ + int rc; + unsigned frame_size = ctxt->src.val; + unsigned nesting_level = ctxt->src2.val & 31; + + if (nesting_level) + return X86EMUL_UNHANDLEABLE; + + rc = push(ctxt, &ctxt->regs[VCPU_REGS_RBP], stack_size(ctxt)); + if (rc != X86EMUL_CONTINUE) + return rc; + assign_masked(&ctxt->regs[VCPU_REGS_RBP], ctxt->regs[VCPU_REGS_RSP], + stack_mask(ctxt)); + assign_masked(&ctxt->regs[VCPU_REGS_RSP], + ctxt->regs[VCPU_REGS_RSP] - frame_size, + stack_mask(ctxt)); + return X86EMUL_CONTINUE; +} + static int em_leave(struct x86_emulate_ctxt *ctxt) { assign_masked(&ctxt->regs[VCPU_REGS_RSP], ctxt->regs[VCPU_REGS_RBP], @@ -3657,7 +3682,8 @@ static struct opcode opcode_table[256] = { I(DstReg | SrcMemFAddr | ModRM | No64 | Src2DS, em_lseg), G(ByteOp, group11), G(0, group11), /* 0xC8 - 0xCF */ - N, I(Stack, em_leave), N, I(ImplicitOps | Stack, em_ret_far), + I(Stack | SrcImmU16 | Src2ImmByte, em_enter), I(Stack, em_leave), + N, I(ImplicitOps | Stack, em_ret_far), D(ImplicitOps), DI(SrcImmByte, intn), D(ImplicitOps | No64), II(ImplicitOps, em_iret, iret), /* 0xD0 - 0xD7 */