From 83fd9629a39ee8a58f1f772a2ca3a7745a4c5743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Mon, 27 Feb 2017 17:09:01 +0000 Subject: vl/cpus: be smarter with icount and MTTCG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sense of the test was inverted. Make it simple, if icount is enabled then we disabled MTTCG by default. If the user tries to force MTTCG upon us then we tell them "no". Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- cpus.c | 7 +++---- vl.c | 7 ++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/cpus.c b/cpus.c index c857ad2..6a817fe 100644 --- a/cpus.c +++ b/cpus.c @@ -181,10 +181,7 @@ static bool check_tcg_memory_orders_compatible(void) static bool default_mttcg_enabled(void) { - QemuOpts *icount_opts = qemu_find_opts_singleton("icount"); - const char *rr = qemu_opt_get(icount_opts, "rr"); - - if (rr || TCG_OVERSIZED_GUEST) { + if (use_icount || TCG_OVERSIZED_GUEST) { return false; } else { #ifdef TARGET_SUPPORTS_MTTCG @@ -202,6 +199,8 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp) if (strcmp(t, "multi") == 0) { if (TCG_OVERSIZED_GUEST) { error_setg(errp, "No MTTCG when guest word size > hosts"); + } else if (use_icount) { + error_setg(errp, "No MTTCG when icount is enabled"); } else { if (!check_tcg_memory_orders_compatible()) { error_report("Guest expects a stronger memory ordering " diff --git a/vl.c b/vl.c index 7f1644a..1a95500 100644 --- a/vl.c +++ b/vl.c @@ -4055,8 +4055,6 @@ int main(int argc, char **argv, char **envp) replay_configure(icount_opts); - qemu_tcg_configure(accel_opts, &error_fatal); - machine_class = select_machine(); set_memory_options(&ram_slots, &maxram_size, machine_class); @@ -4423,14 +4421,13 @@ int main(int argc, char **argv, char **envp) if (!tcg_enabled()) { error_report("-icount is not allowed with hardware virtualization"); exit(1); - } else if (qemu_tcg_mttcg_enabled()) { - error_report("-icount does not currently work with MTTCG"); - exit(1); } configure_icount(icount_opts, &error_abort); qemu_opts_del(icount_opts); } + qemu_tcg_configure(accel_opts, &error_fatal); + if (default_net) { QemuOptsList *net = qemu_find_opts("net"); qemu_opts_set(net, NULL, "type", "nic", &error_abort); -- cgit v1.1 From 72c1701f62e8d44eb24a0583a958edc280105455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 28 Feb 2017 14:35:14 +0000 Subject: target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This suppresses the incorrect warning when forcing MTTCG for x86 guests on x86 hosts. A future patch will still warn when TARGET_SUPPORT_MTTCG hasn't been defined for the guest (which is still pending for x86). Reported-by: Paolo Bonzini Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Eduardo Habkost Acked-by: Eduardo Habkost --- target/i386/cpu.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index ac2ad6d..fb09aee 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -30,6 +30,9 @@ #define TARGET_LONG_BITS 32 #endif +/* The x86 has a strong memory model with some store-after-load re-ordering */ +#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD) + /* Maximum instruction code size */ #define TARGET_MAX_INSN_SIZE 16 -- cgit v1.1 From c34c762015fec023c3ea5cf3629cbac462a80973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 28 Feb 2017 14:40:17 +0000 Subject: cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While we may fail the memory ordering check later that can be confusing. So in cases where TARGET_SUPPORT_MTTCG has yet to be defined we should say so specifically. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- cpus.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cpus.c b/cpus.c index 6a817fe..69e2185 100644 --- a/cpus.c +++ b/cpus.c @@ -202,6 +202,10 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp) } else if (use_icount) { error_setg(errp, "No MTTCG when icount is enabled"); } else { +#ifndef TARGET_SUPPORT_MTTCG + error_report("Guest not yet converted to MTTCG - " + "you may get unexpected results"); +#endif if (!check_tcg_memory_orders_compatible()) { error_report("Guest expects a stronger memory ordering " "than the host provides"); -- cgit v1.1 From 5ee5993001cf32addb86a92e2ae8cb090fbc1462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Wed, 1 Mar 2017 13:20:02 +0000 Subject: sparc/sparc64: grab BQL before calling cpu_check_irqs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IRQ modification is part of device emulation and should be done while the BQL is held to prevent races when MTTCG is enabled. This adds assertions in the hw emulation layer and wraps the calls from helpers in the BQL. Reported-by: Mark Cave-Ayland Signed-off-by: Alex Bennée --- hw/sparc/sun4m.c | 3 +++ hw/sparc64/sparc64.c | 3 +++ target/sparc/int64_helper.c | 3 +++ target/sparc/win_helper.c | 13 +++++++++++++ 4 files changed, 22 insertions(+) diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 61416a6..873cd7d 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -142,6 +142,9 @@ void cpu_check_irqs(CPUSPARCState *env) { CPUState *cs; + /* We should be holding the BQL before we mess with IRQs */ + g_assert(qemu_mutex_iothread_locked()); + if (env->pil_in && (env->interrupt_index == 0 || (env->interrupt_index & ~15) == TT_EXTINT)) { unsigned int i; diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c index b3d219c..4e4fdab 100644 --- a/hw/sparc64/sparc64.c +++ b/hw/sparc64/sparc64.c @@ -55,6 +55,9 @@ void cpu_check_irqs(CPUSPARCState *env) uint32_t pil = env->pil_in | (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER)); + /* We should be holding the BQL before we mess with IRQs */ + g_assert(qemu_mutex_iothread_locked()); + /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */ if (env->ivec_status & 0x20) { return; diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c index 605747c..f942973 100644 --- a/target/sparc/int64_helper.c +++ b/target/sparc/int64_helper.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/helper-proto.h" #include "exec/log.h" @@ -208,7 +209,9 @@ static bool do_modify_softint(CPUSPARCState *env, uint32_t value) env->softint = value; #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif return true; diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 71b3dd3..154279e 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" @@ -82,6 +83,7 @@ void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val) #endif } +/* Called with BQL held */ void cpu_put_psr(CPUSPARCState *env, target_ulong val) { cpu_put_psr_raw(env, val); @@ -153,7 +155,10 @@ void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) if ((new_psr & PSR_CWP) >= env->nwindows) { cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); } else { + /* cpu_put_psr may trigger interrupts, hence BQL */ + qemu_mutex_lock_iothread(); cpu_put_psr(env, new_psr); + qemu_mutex_unlock_iothread(); } } @@ -368,7 +373,9 @@ void helper_wrpstate(CPUSPARCState *env, target_ulong new_state) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -381,7 +388,9 @@ void helper_wrpil(CPUSPARCState *env, target_ulong new_pil) env->psrpil = new_pil; if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -408,7 +417,9 @@ void helper_done(CPUSPARCState *env) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -435,7 +446,9 @@ void helper_retry(CPUSPARCState *env) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } -- cgit v1.1 From 278f5e98c647f74e93636e8b6f9ba20a71765a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Wed, 1 Mar 2017 16:22:40 +0000 Subject: s390x/misc_helper.c: wrap IO instructions in BQL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helpers that can trigger IO events (including interrupts) need to be protected by the BQL. I've updated all the helpers that call into an ioinst_handle_* functions. Reported-by: Thomas Huth Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé --- target/s390x/misc_helper.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index 3cb942e..93b0e61 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/memory.h" #include "qemu/host-utils.h" @@ -551,61 +552,81 @@ uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1, void HELPER(xsch)(CPUS390XState *env, uint64_t r1) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_xsch(cpu, r1); + qemu_mutex_unlock_iothread(); } void HELPER(csch)(CPUS390XState *env, uint64_t r1) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_csch(cpu, r1); + qemu_mutex_unlock_iothread(); } void HELPER(hsch)(CPUS390XState *env, uint64_t r1) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_hsch(cpu, r1); + qemu_mutex_unlock_iothread(); } void HELPER(msch)(CPUS390XState *env, uint64_t r1, uint64_t inst) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_msch(cpu, r1, inst >> 16); + qemu_mutex_unlock_iothread(); } void HELPER(rchp)(CPUS390XState *env, uint64_t r1) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_rchp(cpu, r1); + qemu_mutex_unlock_iothread(); } void HELPER(rsch)(CPUS390XState *env, uint64_t r1) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_rsch(cpu, r1); + qemu_mutex_unlock_iothread(); } void HELPER(ssch)(CPUS390XState *env, uint64_t r1, uint64_t inst) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_ssch(cpu, r1, inst >> 16); + qemu_mutex_unlock_iothread(); } void HELPER(stsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_stsch(cpu, r1, inst >> 16); + qemu_mutex_unlock_iothread(); } void HELPER(tsch)(CPUS390XState *env, uint64_t r1, uint64_t inst) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_tsch(cpu, r1, inst >> 16); + qemu_mutex_unlock_iothread(); } void HELPER(chsc)(CPUS390XState *env, uint64_t inst) { S390CPU *cpu = s390_env_get_cpu(env); + qemu_mutex_lock_iothread(); ioinst_handle_chsc(cpu, inst >> 16); + qemu_mutex_unlock_iothread(); } #endif -- cgit v1.1 From 47e20887970c3f267a4be9afacb72dbd51e6655f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Wed, 1 Mar 2017 20:29:10 +0000 Subject: target/xtensa: hold BQL for interrupt processing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure we have the BQL held when processing interrupts. Reported-by: Thomas Huth Signed-off-by: Alex Bennée Acked-by: Max Filippov --- target/xtensa/helper.c | 1 + target/xtensa/op_helper.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index c67d715..bcd0b77 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -217,6 +217,7 @@ static void handle_interrupt(CPUXtensaState *env) } } +/* Called from cpu_handle_interrupt with BQL held */ void xtensa_cpu_do_interrupt(CPUState *cs) { XtensaCPU *cpu = XTENSA_CPU(cs); diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index af27234..519fbed 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -26,6 +26,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/helper-proto.h" #include "qemu/host-utils.h" @@ -381,7 +382,11 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) env->pc = pc; env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) | (intlevel << PS_INTLEVEL_SHIFT); + + qemu_mutex_lock_iothread(); check_interrupts(env); + qemu_mutex_unlock_iothread(); + if (env->pending_irq_level) { cpu_loop_exit(CPU(xtensa_env_get_cpu(env))); return; @@ -426,7 +431,9 @@ void HELPER(update_ccompare)(CPUXtensaState *env, uint32_t i) void HELPER(check_interrupts)(CPUXtensaState *env) { + qemu_mutex_lock_iothread(); check_interrupts(env); + qemu_mutex_unlock_iothread(); } void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr) -- cgit v1.1 From d8b2239bcd8872a5c5f7534d1658fc2365caab2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 2 Mar 2017 10:31:32 +0000 Subject: translate-all: exit cpu_restore_state early if translating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The translation code uses cpu_ld*_code which can trigger a tlb_fill which if it fails will erroneously attempts a fault resolution. This never works during translation as the TB being generated hasn't been added yet. The target should have checked retaddr before calling cpu_restore_state but for those that have yet to be fixed we do it here to avoid a recursive tb_lock() under MTTCG's new locking regime. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- translate-all.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/translate-all.c b/translate-all.c index d42d003..34480ae 100644 --- a/translate-all.c +++ b/translate-all.c @@ -333,6 +333,19 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr) TranslationBlock *tb; bool r = false; + /* A retaddr of zero is invalid so we really shouldn't have ended + * up here. The target code has likely forgotten to check retaddr + * != 0 before attempting to restore state. We return early to + * avoid blowing up on a recursive tb_lock(). The target must have + * previously survived a failed cpu_restore_state because + * tb_find_pc(0) would have failed anyway. It still should be + * fixed though. + */ + + if (!retaddr) { + return r; + } + tb_lock(); tb = tb_find_pc(retaddr); if (tb) { -- cgit v1.1 From d394698d73836d1c50545bdb32dc58d09708fcfb Mon Sep 17 00:00:00 2001 From: Yongbok Kim Date: Fri, 3 Mar 2017 11:20:21 +0000 Subject: target/mips: hold BQL for timer interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hold BQL when accessing timer which can cause interrupts Signed-off-by: Yongbok Kim Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée --- target/mips/op_helper.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c index b683fcb..e5f3ea4 100644 --- a/target/mips/op_helper.c +++ b/target/mips/op_helper.c @@ -17,6 +17,7 @@ * License along with this library; if not, see . */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "qemu/host-utils.h" #include "exec/helper-proto.h" @@ -827,7 +828,11 @@ target_ulong helper_mftc0_tcschefback(CPUMIPSState *env) target_ulong helper_mfc0_count(CPUMIPSState *env) { - return (int32_t)cpu_mips_get_count(env); + int32_t count; + qemu_mutex_lock_iothread(); + count = (int32_t) cpu_mips_get_count(env); + qemu_mutex_unlock_iothread(); + return count; } target_ulong helper_mftc0_entryhi(CPUMIPSState *env) @@ -1375,7 +1380,9 @@ void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1) { + qemu_mutex_lock_iothread(); cpu_mips_store_count(env, arg1); + qemu_mutex_unlock_iothread(); } void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) @@ -1424,7 +1431,9 @@ void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1) { + qemu_mutex_lock_iothread(); cpu_mips_store_compare(env, arg1); + qemu_mutex_unlock_iothread(); } void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1) @@ -1475,7 +1484,9 @@ void helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1) { + qemu_mutex_lock_iothread(); cpu_mips_store_cause(env, arg1); + qemu_mutex_unlock_iothread(); } void helper_mttc0_cause(CPUMIPSState *env, target_ulong arg1) @@ -2296,12 +2307,16 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env) target_ulong helper_rdhwr_cc(CPUMIPSState *env) { + int32_t count; check_hwrena(env, 2, GETPC()); #ifdef CONFIG_USER_ONLY - return env->CP0_Count; + count = env->CP0_Count; #else - return (int32_t)cpu_mips_get_count(env); + qemu_mutex_lock_iothread(); + count = (int32_t)cpu_mips_get_count(env); + qemu_mutex_unlock_iothread(); #endif + return count; } target_ulong helper_rdhwr_ccres(CPUMIPSState *env) -- cgit v1.1 From 10cde894b63146139f981857e4eedf756fa53dcb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 7 Mar 2017 12:37:36 +0100 Subject: target-i386: defer VMEXIT to do_interrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Paths through the softmmu code during code generation now need to be audited to check for double locking of tb_lock. In particular, VMEXIT can take tb_lock through cpu_vmexit -> cpu_x86_update_cr4 -> tlb_flush. To avoid this, split VMEXIT delivery in two parts, similar to what is done with exceptions. cpu_vmexit only records the VMEXIT exit code and information, and cc->do_interrupt can then deliver it when it is safe to take the lock. Reported-by: Alexander Boettcher Suggested-by: Richard Henderson Tested-by: Alexander Boettcher Signed-off-by: Paolo Bonzini Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- target/i386/cpu.h | 2 ++ target/i386/seg_helper.c | 20 +++++++++++--------- target/i386/svm_helper.c | 22 +++++++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index fb09aee..406cb24 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -697,6 +697,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define EXCP_SYSCALL 0x100 /* only happens in user only emulation for syscall instruction */ +#define EXCP_VMEXIT 0x100 /* i386-specific interrupt pending bits. */ #define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1 @@ -1632,6 +1633,7 @@ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, uint64_t param, uintptr_t retaddr); void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1, uintptr_t retaddr); +void do_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1); /* seg_helper.c */ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c index 5c845dc..0374031 100644 --- a/target/i386/seg_helper.c +++ b/target/i386/seg_helper.c @@ -1297,15 +1297,17 @@ void x86_cpu_do_interrupt(CPUState *cs) /* successfully delivered */ env->old_exception = -1; #else - /* simulate a real cpu exception. On i386, it can - trigger new exceptions, but we do not handle - double or triple faults yet. */ - do_interrupt_all(cpu, cs->exception_index, - env->exception_is_int, - env->error_code, - env->exception_next_eip, 0); - /* successfully delivered */ - env->old_exception = -1; + if (cs->exception_index >= EXCP_VMEXIT) { + assert(env->old_exception == -1); + do_vmexit(env, cs->exception_index - EXCP_VMEXIT, env->error_code); + } else { + do_interrupt_all(cpu, cs->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip, 0); + /* successfully delivered */ + env->old_exception = -1; + } #endif } diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c index 78d8df4..59e8b50 100644 --- a/target/i386/svm_helper.c +++ b/target/i386/svm_helper.c @@ -580,12 +580,10 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, } } -/* Note: currently only 32 bits of exit_code are used */ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, uintptr_t retaddr) { CPUState *cs = CPU(x86_env_get_cpu(env)); - uint32_t int_ctl; if (retaddr) { cpu_restore_state(cs, retaddr); @@ -598,6 +596,19 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, control.exit_info_2)), env->eip); + cs->exception_index = EXCP_VMEXIT + exit_code; + env->error_code = exit_info_1; + + /* remove any pending exception */ + env->old_exception = -1; + cpu_loop_exit(cs); +} + +void do_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1) +{ + CPUState *cs = CPU(x86_env_get_cpu(env)); + uint32_t int_ctl; + if (env->hflags & HF_INHIBIT_IRQ_MASK) { x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_state), @@ -759,13 +770,6 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, /* If the host's rIP reloaded by #VMEXIT is outside the limit of the host's code segment or non-canonical (in the case of long mode), a #GP fault is delivered inside the host. */ - - /* remove any pending exception */ - cs->exception_index = -1; - env->error_code = 0; - env->old_exception = -1; - - cpu_loop_exit(cs); } #endif -- cgit v1.1 From 6568da459b611845ef55526cd23afc9fa9f4647f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 2 Mar 2017 14:07:16 +0000 Subject: target/arm/helper: make it clear the EC field is also in hex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ..just like the rest of the displayed ESR register. Otherwise people might scratch their heads if a not obviously hex number is displayed for the EC field. Signed-off-by: Alex Bennée Reviewed-by: Peter Maydell Reviewed-by: KONRAD Frederic Reviewed-by: Philippe Mathieu-Daudé --- target/arm/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 3f4211b..76b608f 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6857,7 +6857,7 @@ void arm_cpu_do_interrupt(CPUState *cs) new_el); if (qemu_loglevel_mask(CPU_LOG_INT) && !excp_is_internal(cs->exception_index)) { - qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n", + qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n", env->exception.syndrome >> ARM_EL_EC_SHIFT, env->exception.syndrome); } -- cgit v1.1 From 68bf93ce9dc5c84c45a827ce2bd6eab768524e79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Thu, 2 Mar 2017 19:08:52 +0000 Subject: hw/intc/arm_gic: modernise the DPRINTF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While I was debugging the icount issues I realised a bunch of the messages look quite similar. I've fixed this by including __func__ in the debug print. At the same time I move the a modern if (GATE) style printf which ensures the compiler can check for format string errors even if the code gets optimised away in the non-DEBUG_GIC case. Signed-off-by: Alex Bennée Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé --- hw/intc/arm_gic.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 8e5a9d8..b305d90 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -26,15 +26,20 @@ #include "qemu/log.h" #include "trace.h" -//#define DEBUG_GIC +/* #define DEBUG_GIC */ #ifdef DEBUG_GIC -#define DPRINTF(fmt, ...) \ -do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0) +#define DEBUG_GIC_GATE 1 #else -#define DPRINTF(fmt, ...) do {} while(0) +#define DEBUG_GIC_GATE 0 #endif +#define DPRINTF(fmt, ...) do { \ + if (DEBUG_GIC_GATE) { \ + fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); \ + } \ + } while (0) + static const uint8_t gic_id_11mpcore[] = { 0x00, 0x00, 0x00, 0x00, 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 }; -- cgit v1.1