From nobody Mon Feb 9 17:36:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487267603495774.5999479761185; Thu, 16 Feb 2017 09:53:23 -0800 (PST) Received: from localhost ([::1]:48653 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceQF6-0005GZ-5r for importer@patchew.org; Thu, 16 Feb 2017 12:53:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51029) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ceQ11-0007jy-2r for qemu-devel@nongnu.org; Thu, 16 Feb 2017 12:38:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ceQ0y-0002IB-N3 for qemu-devel@nongnu.org; Thu, 16 Feb 2017 12:38:47 -0500 Received: from mail-wr0-x244.google.com ([2a00:1450:400c:c0c::244]:33824) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ceQ0y-0002Gm-DH; Thu, 16 Feb 2017 12:38:44 -0500 Received: by mail-wr0-x244.google.com with SMTP id c4so2903293wrd.1; Thu, 16 Feb 2017 09:38:44 -0800 (PST) Received: from 640k.lan (94-39-187-56.adsl-ull.clienti.tiscali.it. [94.39.187.56]) by smtp.gmail.com with ESMTPSA id m83sm1065397wmc.33.2017.02.16.09.38.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Feb 2017 09:38:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=kBJ5EoWjXGkN1YLhPIW7L46+yXx2mnBYMTEV4x5Il58=; b=L/1DCZYor3z5VgwEqlZphrBNrDBtPTKAgPTgn5msrEo2q/1HelXoA3NextE43WLQxd 2JpFQgK70jVlIG+SqQqF7RK8CrwclXRBfc8HmNO33MgtLD/kmLUNsi+kxq0SCVcqc/ZP 2ckk39FtupHp5+o5kgh3d/yG4cDRgB14dEBKaCYScFY++8ibEHz44BAkwvdM96lfEBRh 0AV0jzuiSaESaJU3GSCBdWVBmdkfcs9Shtm95myhJy1y4olyBz7cfEUoJhDthgf1dBoH REX4C0pmH22Smf+RV75cDjOPxmHuqnKdxmc7y6pzkZePwZcP/YNm1SYB+9kDtvI5i6Jn bxmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=kBJ5EoWjXGkN1YLhPIW7L46+yXx2mnBYMTEV4x5Il58=; b=tqDi2bWnVGuajEhp61m0BjWp/OlJ3OuYW73qSY+XY8Kir8GRNz88QGdDpbAZl9a52Q +JC4MGQ1c8ifqqZ0j2Vx+l82oEVl7V0fpgTByVzceuvh5gB7NW3ib8yeZgm38l68kgyz tPprBO6if8iwJ1ezf4ig7fCMgb8M4KpumcfCNUvFNAUMtFvScSgzGYw6TcVKKCOvOcm5 CDK4hvX4u8v2xueORNAleybawUjLk+oPy+Q2HL67VRk/UQD7R2AN4juXR8eXBeFik2rA JxXL/41mQDm2ez7gCqP8gHaXM/P8JDBE7y7JMVNKxohMV/99k9yx2RLvuLg28elYOdmi erUw== X-Gm-Message-State: AMke39l1t4GMawlYiUyeVDzS1gNL65k894lydMl8Q4P8JcVii7SpDU6/+KaTcwmT+/KI9Q== X-Received: by 10.223.150.88 with SMTP id c24mr3151591wra.190.1487266722855; Thu, 16 Feb 2017 09:38:42 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 16 Feb 2017 18:38:38 +0100 Message-Id: <1487266718-108184-2-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1487266718-108184-1-git-send-email-pbonzini@redhat.com> References: <1487266718-108184-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c0c::244 Subject: [Qemu-devel] [PULL 23/23] target-i386: correctly propagate retaddr into SVM helpers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Commit 2afbdf8 ("target-i386: exception handling for memory helpers", 2015-09-15) changed tlb_fill's cpu_restore_state+raise_exception_err to raise_exception_err_ra. After this change, the cpu_restore_state and raise_exception_err's cpu_loop_exit are merged into raise_exception_err_ra's cpu_loop_exit_restore. This actually fixed some bugs, but when SVM is enabled there is a second path from raise_exception_err_ra to cpu_loop_exit. This is the VMEXIT path, and now cpu_vmexit is called without a cpu_restore_state before. The fix is to pass the retaddr to cpu_vmexit (via cpu_svm_check_intercept_param). All helpers can now use GETPC() to pass the correct retaddr, too. Cc: qemu-stable@nongnu.org Fixes: 2afbdf84807d673eb682cb78158e11cdacbf4673 Reported-by: Alexander Boettcher Tested-by: Alexander Boettcher Signed-off-by: Paolo Bonzini --- cpu-exec.c | 2 +- target/i386/cpu.h | 5 ++-- target/i386/excp_helper.c | 11 ++++---- target/i386/helper.h | 1 - target/i386/misc_helper.c | 24 ++++++++--------- target/i386/seg_helper.c | 6 ++--- target/i386/svm_helper.c | 65 ++++++++++++++++++++++---------------------= ---- 7 files changed, 56 insertions(+), 58 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index b8ebb5c..142a586 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -491,7 +491,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, X86CPU *x86_cpu =3D X86_CPU(cpu); CPUArchState *env =3D &x86_cpu->env; replay_interrupt(); - cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0, 0); do_cpu_init(x86_cpu); cpu->exception_index =3D EXCP_HALTED; return true; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 4d788d5..8df124f 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1621,8 +1621,9 @@ void helper_lock_init(void); =20 /* svm_helper.c */ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, - uint64_t param); -void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1); + uint64_t param, uintptr_t retaddr); +void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1, + uintptr_t retaddr); =20 /* seg_helper.c */ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); diff --git a/target/i386/excp_helper.c b/target/i386/excp_helper.c index f0dc499..ee596c6 100644 --- a/target/i386/excp_helper.c +++ b/target/i386/excp_helper.c @@ -39,7 +39,8 @@ void helper_raise_exception(CPUX86State *env, int excepti= on_index) * needed. It should only be called, if this is not an interrupt. * Returns the new exception number. */ -static int check_exception(CPUX86State *env, int intno, int *error_code) +static int check_exception(CPUX86State *env, int intno, int *error_code, + uintptr_t retaddr) { int first_contributory =3D env->old_exception =3D=3D 0 || (env->old_exception >=3D 10 && @@ -53,7 +54,7 @@ static int check_exception(CPUX86State *env, int intno, i= nt *error_code) #if !defined(CONFIG_USER_ONLY) if (env->old_exception =3D=3D EXCP08_DBLE) { if (env->hflags & HF_SVMI_MASK) { - cpu_vmexit(env, SVM_EXIT_SHUTDOWN, 0); /* does not return */ + cpu_vmexit(env, SVM_EXIT_SHUTDOWN, 0, retaddr); /* does not re= turn */ } =20 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); @@ -93,10 +94,10 @@ static void QEMU_NORETURN raise_interrupt2(CPUX86State = *env, int intno, =20 if (!is_int) { cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno, - error_code); - intno =3D check_exception(env, intno, &error_code); + error_code, retaddr); + intno =3D check_exception(env, intno, &error_code, retaddr); } else { - cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_SWINT, 0, retaddr); } =20 cs->exception_index =3D intno; diff --git a/target/i386/helper.h b/target/i386/helper.h index 4c1aaff..6fb8fb9 100644 --- a/target/i386/helper.h +++ b/target/i386/helper.h @@ -99,7 +99,6 @@ DEF_HELPER_2(inl, tl, env, i32) DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl) =20 DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64) -DEF_HELPER_3(vmexit, void, env, i32, i64) DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32) DEF_HELPER_3(vmrun, void, env, int, int) DEF_HELPER_1(vmmcall, void, env) diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c index 5029efe..ca2ea09 100644 --- a/target/i386/misc_helper.c +++ b/target/i386/misc_helper.c @@ -101,7 +101,7 @@ void helper_cpuid(CPUX86State *env) { uint32_t eax, ebx, ecx, edx; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0, GETPC()); =20 cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_E= CX], &eax, &ebx, &ecx, &edx); @@ -125,7 +125,7 @@ target_ulong helper_read_crN(CPUX86State *env, int reg) { target_ulong val; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC()= ); switch (reg) { default: val =3D env->cr[reg]; @@ -143,7 +143,7 @@ target_ulong helper_read_crN(CPUX86State *env, int reg) =20 void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) { - cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC(= )); switch (reg) { case 0: cpu_x86_update_cr0(env, t0); @@ -179,7 +179,7 @@ void helper_invlpg(CPUX86State *env, target_ulong addr) { X86CPU *cpu =3D x86_env_get_cpu(env); =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC()); tlb_flush_page(CPU(cpu), addr); } =20 @@ -190,7 +190,7 @@ void helper_rdtsc(CPUX86State *env) if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) !=3D 0= )) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } - cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0, GETPC()); =20 val =3D cpu_get_tsc(env) + env->tsc_offset; env->regs[R_EAX] =3D (uint32_t)(val); @@ -208,7 +208,7 @@ void helper_rdpmc(CPUX86State *env) if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) !=3D 0= )) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } - cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC()); =20 /* currently unimplemented */ qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n"); @@ -228,7 +228,7 @@ void helper_wrmsr(CPUX86State *env) { uint64_t val; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1); + cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC()); =20 val =3D ((uint32_t)env->regs[R_EAX]) | ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); @@ -388,7 +388,7 @@ void helper_rdmsr(CPUX86State *env) { uint64_t val; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC()); =20 switch ((uint32_t)env->regs[R_ECX]) { case MSR_IA32_SYSENTER_CS: @@ -557,7 +557,7 @@ void helper_hlt(CPUX86State *env, int next_eip_addend) { X86CPU *cpu =3D x86_env_get_cpu(env); =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC()); env->eip +=3D next_eip_addend; =20 do_hlt(cpu); @@ -569,7 +569,7 @@ void helper_monitor(CPUX86State *env, target_ulong ptr) raise_exception_ra(env, EXCP0D_GPF, GETPC()); } /* XXX: store address? */ - cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC()); } =20 void helper_mwait(CPUX86State *env, int next_eip_addend) @@ -580,7 +580,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend) if ((uint32_t)env->regs[R_ECX] !=3D 0) { raise_exception_ra(env, EXCP0D_GPF, GETPC()); } - cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC()); env->eip +=3D next_eip_addend; =20 cpu =3D x86_env_get_cpu(env); @@ -597,7 +597,7 @@ void helper_pause(CPUX86State *env, int next_eip_addend) { X86CPU *cpu =3D x86_env_get_cpu(env); =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC()); env->eip +=3D next_eip_addend; =20 do_pause(cpu); diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c index d24574d..5c845dc 100644 --- a/target/i386/seg_helper.c +++ b/target/i386/seg_helper.c @@ -1335,7 +1335,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interru= pt_request) } else if (env->hflags2 & HF2_GIF_MASK) { if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { - cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0); cs->interrupt_request &=3D ~CPU_INTERRUPT_SMI; do_smm_enter(cpu); ret =3D true; @@ -1356,7 +1356,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interru= pt_request) (env->eflags & IF_MASK && !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { int intno; - cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0); cs->interrupt_request &=3D ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno =3D cpu_get_pic_interrupt(env); @@ -1372,7 +1372,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interru= pt_request) !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; /* FIXME: this should respect TPR */ - cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0); intno =3D x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); qemu_log_mask(CPU_LOG_TB_IN_ASM, diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c index 210f6aa..78d8df4 100644 --- a/target/i386/svm_helper.c +++ b/target/i386/svm_helper.c @@ -60,11 +60,8 @@ void helper_invlpga(CPUX86State *env, int aflag) { } =20 -void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_inf= o_1) -{ -} - -void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1) +void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1, + uintptr_t retaddr) { } =20 @@ -74,7 +71,7 @@ void helper_svm_check_intercept_param(CPUX86State *env, u= int32_t type, } =20 void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, - uint64_t param) + uint64_t param, uintptr_t retaddr) { } =20 @@ -130,7 +127,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next= _eip_addend) uint32_t event_inj; uint32_t int_ctl; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC()); =20 if (aflag =3D=3D 2) { addr =3D env->regs[R_EAX]; @@ -355,7 +352,7 @@ void helper_vmrun(CPUX86State *env, int aflag, int next= _eip_addend) =20 void helper_vmmcall(CPUX86State *env) { - cpu_svm_check_intercept_param(env, SVM_EXIT_VMMCALL, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_VMMCALL, 0, GETPC()); raise_exception(env, EXCP06_ILLOP); } =20 @@ -364,7 +361,7 @@ void helper_vmload(CPUX86State *env, int aflag) CPUState *cs =3D CPU(x86_env_get_cpu(env)); target_ulong addr; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC()); =20 if (aflag =3D=3D 2) { addr =3D env->regs[R_EAX]; @@ -404,7 +401,7 @@ void helper_vmsave(CPUX86State *env, int aflag) CPUState *cs =3D CPU(x86_env_get_cpu(env)); target_ulong addr; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC()); =20 if (aflag =3D=3D 2) { addr =3D env->regs[R_EAX]; @@ -445,19 +442,19 @@ void helper_vmsave(CPUX86State *env, int aflag) =20 void helper_stgi(CPUX86State *env) { - cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC()); env->hflags2 |=3D HF2_GIF_MASK; } =20 void helper_clgi(CPUX86State *env) { - cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC()); env->hflags2 &=3D ~HF2_GIF_MASK; } =20 void helper_skinit(CPUX86State *env) { - cpu_svm_check_intercept_param(env, SVM_EXIT_SKINIT, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_SKINIT, 0, GETPC()); /* XXX: not implemented */ raise_exception(env, EXCP06_ILLOP); } @@ -467,7 +464,7 @@ void helper_invlpga(CPUX86State *env, int aflag) X86CPU *cpu =3D x86_env_get_cpu(env); target_ulong addr; =20 - cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0); + cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0, GETPC()); =20 if (aflag =3D=3D 2) { addr =3D env->regs[R_EAX]; @@ -480,8 +477,8 @@ void helper_invlpga(CPUX86State *env, int aflag) tlb_flush_page(CPU(cpu), addr); } =20 -void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, - uint64_t param) +void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, + uint64_t param, uintptr_t retaddr) { CPUState *cs =3D CPU(x86_env_get_cpu(env)); =20 @@ -491,27 +488,27 @@ void helper_svm_check_intercept_param(CPUX86State *en= v, uint32_t type, switch (type) { case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR0 + 8: if (env->intercept_cr_read & (1 << (type - SVM_EXIT_READ_CR0))) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR0 + 8: if (env->intercept_cr_write & (1 << (type - SVM_EXIT_WRITE_CR0))) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR0 + 7: if (env->intercept_dr_read & (1 << (type - SVM_EXIT_READ_DR0))) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR0 + 7: if (env->intercept_dr_write & (1 << (type - SVM_EXIT_WRITE_DR0))) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 31: if (env->intercept_exceptions & (1 << (type - SVM_EXIT_EXCP_BASE))= ) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; case SVM_EXIT_MSR: @@ -538,28 +535,28 @@ void helper_svm_check_intercept_param(CPUX86State *en= v, uint32_t type, t0 %=3D 8; break; default: - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); t0 =3D 0; t1 =3D 0; break; } if (x86_ldub_phys(cs, addr + t1) & ((1 << param) << t0)) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } } break; default: if (env->intercept & (1ULL << (type - SVM_EXIT_INTR))) { - helper_vmexit(env, type, param); + cpu_vmexit(env, type, param, retaddr); } break; } } =20 -void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, - uint64_t param) +void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, + uint64_t param) { - helper_svm_check_intercept_param(env, type, param); + cpu_svm_check_intercept_param(env, type, param, GETPC()); } =20 void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, @@ -578,17 +575,22 @@ void helper_svm_check_io(CPUX86State *env, uint32_t p= ort, uint32_t param, x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_inf= o_2), env->eip + next_eip_addend); - helper_vmexit(env, SVM_EXIT_IOIO, param | (port << 16)); + cpu_vmexit(env, SVM_EXIT_IOIO, param | (port << 16), GETPC()); } } } =20 /* Note: currently only 32 bits of exit_code are used */ -void helper_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_inf= o_1) +void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, + uintptr_t retaddr) { CPUState *cs =3D CPU(x86_env_get_cpu(env)); uint32_t int_ctl; =20 + if (retaddr) { + cpu_restore_state(cs, retaddr); + } + qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n", exit_code, exit_info_1, @@ -766,9 +768,4 @@ void helper_vmexit(CPUX86State *env, uint32_t exit_code= , uint64_t exit_info_1) cpu_loop_exit(cs); } =20 -void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) -{ - helper_vmexit(env, exit_code, exit_info_1); -} - #endif --=20 1.8.3.1