From nobody Mon Feb 9 18:18:43 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1597862140; cv=none; d=zohomail.com; s=zohoarc; b=T7lsumHulbP/nc/nD6s1iVpRiNUv7tllms/EyZccuLDv+PckMvT7PloKQvaxGGZPcUL72hk0DQYl/VpYotQiyHMDcgIGvKpWlsnMdTFegXgPiRBc15J4vM8rxvDv2kKOHT6TR77djLNMo6PUwZwsrOCKhAJlxY9Ps0r7Z8VCmYE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1597862140; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=/lh6DcqLk8tYuQOAaHAbdH6hrmCHOijr801Ci4Vz+6Q=; b=kfrIY1Mv5GnnFZkagm+lZEg6IVHDUxzoip0b8h857LHFVVsnD6P7yyn+dnZkdvjt4pYh59AOYHQ6lJkuGzqYtFO2GVlSB4Ytf7opiXyZd3oF6/pa4WWiZxF7YK7RW4erGIvNmSGQ6mMg/Q5w8SpCKYWb/0ejq4Ol5otSPRKNl6o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 159786214016824.80101095100747; Wed, 19 Aug 2020 11:35:40 -0700 (PDT) Received: from localhost ([::1]:42778 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k8Svy-00030M-HX for importer@patchew.org; Wed, 19 Aug 2020 14:35:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60320) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k8SrA-0003M4-Rk for qemu-devel@nongnu.org; Wed, 19 Aug 2020 14:30:40 -0400 Received: from mail-pj1-x1043.google.com ([2607:f8b0:4864:20::1043]:52837) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1k8Sr2-0001yz-0H for qemu-devel@nongnu.org; Wed, 19 Aug 2020 14:30:40 -0400 Received: by mail-pj1-x1043.google.com with SMTP id kr4so1497708pjb.2 for ; Wed, 19 Aug 2020 11:30:31 -0700 (PDT) Received: from Rfoley-MA01.hsd1.ma.comcast.net (c-73-47-162-176.hsd1.ma.comcast.net. [73.47.162.176]) by smtp.gmail.com with ESMTPSA id p20sm220766pjg.44.2020.08.19.11.30.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Aug 2020 11:30:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/lh6DcqLk8tYuQOAaHAbdH6hrmCHOijr801Ci4Vz+6Q=; b=gx6iCGxpmjzmbVuTgWqDwfkkDMgT93wYkkeV+eX9asPIcMeSSMADFsi78jRKwpQ1Ms QbYGIXNUklkXBri79+mNTsHWo4rJSIly61HLEiyfJrhBQfhpm+ULbu77ojqUO2C/q1DW HoWiHBchRk3Jsxu8reCPHJcg77YNv5dX3XPkxTigNmxyN+RixwAQAdawx8AJbvrCybxN JtLUxhl3yk/9C+caVXavFTmGjZcanwfub3vE6w3Chb9euzMXNGDlHEtOHlUYlJ/O062F JXAcf+FgYKoiIRX1vvzOpTIY6zST47MItHYnRtuxS1JRXWsjsG+SEl1KMcFYux92wh3e d7Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/lh6DcqLk8tYuQOAaHAbdH6hrmCHOijr801Ci4Vz+6Q=; b=SMX1WHD9XyLFN82ZkRl4IcE0QqGNyl85mqMjH3NHiy/Dc+Za88i1ptlKFv8n1PkH1p nxPmQoLok8XpUN2gwEVfn6K1xHfBRGQwTGTRpApErJhM70ZI1gd9TNmZScq8rBHF15yv WFK/RjR3EayZ4+sbk1onFOGyEbVVAPnFueiWCiu7TxdPKP5mXuK1niQLuGNuaVNdlozc W+SD2+pcdz7Cq6t1ldGmZW8/s+MqQTsTum0Qv4G3z30GiJa389VAV8L1CruL1vOTaCNT 67uj4AU+lfq9mH9VCj82HWw+fzZXhJ5Ph/dVMV/MFEMSgI2zUv/MqlFUV6QWoH2Sh4iv FQ7g== X-Gm-Message-State: AOAM532WZaneKdoLqlesOmBp3CeWD6n2aInKXmjEevSf6dacZ4KVpmKf G7X3+I2vllCLLtazTgcVMKJ5qkQzc4uMQo/P X-Google-Smtp-Source: ABdhPJw0AokGI/CH+UsparjD5g1PjVPpg2Q3MGgqM4AgUpQGwgihUNrjWCewEKxKTChfYt/BH7+lYw== X-Received: by 2002:a17:90a:fe91:: with SMTP id co17mr5092937pjb.103.1597861828773; Wed, 19 Aug 2020 11:30:28 -0700 (PDT) From: Robert Foley To: qemu-devel@nongnu.org Subject: [PATCH v2 4/7] target: Push BQL on ->do_interrupt down into per-arch implementation Date: Wed, 19 Aug 2020 14:28:53 -0400 Message-Id: <20200819182856.4893-5-robert.foley@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200819182856.4893-1-robert.foley@linaro.org> References: <20200819182856.4893-1-robert.foley@linaro.org> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1043; envelope-from=robert.foley@linaro.org; helo=mail-pj1-x1043.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Sarah Harris , Cornelia Huck , Sagar Karandikar , David Hildenbrand , Mark Cave-Ayland , Thomas Huth , Jiaxun Yang , Max Filippov , Alistair Francis , "Edgar E. Iglesias" , Guan Xuetao , Eduardo Habkost , Marek Vasut , Yoshinori Sato , Aleksandar Markovic , "open list:PowerPC TCG CPUs" , Richard Henderson , Artyom Tarasenko , Aleksandar Rikalo , robert.foley@linaro.org, "open list:S390 general arch..." , "open list:ARM TCG CPUs" , Michael Rolnik , pbonzini@redhat.com, Stafford Horne , alex.bennee@linaro.org, David Gibson , "open list:RISC-V TCG CPUs" , Bastian Koppelmann , Chris Wulff , Laurent Vivier , Michael Walle , Palmer Dabbelt , peter.puhov@linaro.org, Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" As part of pushing the BQL down into the per-arch implementation, the first change is to remove the holding of BQL from cpu_handle_exception. Next, we made changes per-arch to re-add a new *_do_interrupt function, which gets the BQL and then calls to *_do_interrupt_locked. We also pointed the per-arch ->do_interrupt at the new *_do_interrupt. This patch is part of a series of transitions to move the BQL down into the do_interrupt per arch functions. This set of transitions is needed to maintain bisectability. It is worth mentioning that arm and cris are slightly different. In a prior patch for these arches, we added a new CPUClass method ->do_interrupt_locked. The only difference for arm and cris is that their new *_do_interrupt functions will be able to utilize this new ->do_interrupt_locked method. avr is another exception. avr, arm and cris all had a similar case where their *_cpu_exec_interrupt was calling to the CPUClass ->do_interrupt. This causes an issue when we push the lock down since ->do_interrupt will try to acquire the BQL, but the calling context already has it. To solve this for arm and cris, we added a new CPUCLass method as explained above. Moreover, it was actually required for these arches since they have more than one possible value of ->do_interrupt. In the case of avr, there is only one possible value of ->do_interrupt, so for that reason we changed the avr_cpu_exec_interrupt to call directly to avr_cpu_do_interrupt_locked rather than call cc->do_interrupt. The purpose of this set of changes is to set the groundwork so that an arch could move towards removing the BQL from the cpu_handle_interrupt/exception paths. This approach was suggested by Paolo Bonzini. For reference, here are key posts in the discussion, explaining the reasoning/benefits of this approach. https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg01517.html https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00784.html https://lists.gnu.org/archive/html/qemu-devel/2020-07/msg08731.html https://lists.gnu.org/archive/html/qemu-devel/2020-08/msg00044.html Signed-off-by: Robert Foley --- accel/tcg/cpu-exec.c | 2 -- target/alpha/cpu.c | 2 +- target/alpha/cpu.h | 2 +- target/alpha/helper.c | 9 ++++++++- target/arm/cpu.c | 2 +- target/arm/cpu.h | 2 ++ target/arm/cpu_tcg.c | 2 +- target/arm/helper.c | 8 ++++++++ target/avr/cpu.c | 2 +- target/avr/cpu.h | 2 +- target/avr/helper.c | 16 ++++++++++++---- target/cris/cpu.c | 7 +------ target/cris/cpu.h | 1 + target/cris/helper.c | 8 ++++++++ target/hppa/cpu.c | 2 +- target/hppa/cpu.h | 2 +- target/hppa/int_helper.c | 9 ++++++++- target/i386/cpu.c | 2 +- target/i386/cpu.h | 2 +- target/i386/seg_helper.c | 9 ++++++++- target/lm32/cpu.c | 2 +- target/lm32/cpu.h | 2 +- target/lm32/helper.c | 9 ++++++++- target/m68k/cpu.c | 2 +- target/m68k/cpu.h | 2 +- target/m68k/op_helper.c | 11 +++++++++-- target/microblaze/cpu.c | 2 +- target/microblaze/cpu.h | 2 +- target/microblaze/helper.c | 11 +++++++++-- target/mips/cpu.c | 2 +- target/mips/helper.c | 9 ++++++++- target/mips/internal.h | 2 +- target/nios2/cpu.c | 2 +- target/nios2/cpu.h | 1 + target/nios2/helper.c | 9 +++++++++ target/openrisc/cpu.c | 2 +- target/openrisc/cpu.h | 2 +- target/openrisc/interrupt.c | 9 ++++++++- target/ppc/cpu.h | 1 + target/ppc/excp_helper.c | 7 +++++++ target/ppc/translate_init.inc.c | 2 +- target/riscv/cpu.c | 2 +- target/riscv/cpu.h | 2 +- target/riscv/cpu_helper.c | 11 ++++++++++- target/rx/cpu.c | 2 +- target/rx/cpu.h | 1 + target/rx/helper.c | 7 +++++++ target/s390x/cpu.c | 2 +- target/s390x/excp_helper.c | 7 +++++++ target/s390x/internal.h | 1 + target/sh4/cpu.c | 2 +- target/sh4/cpu.h | 2 +- target/sh4/helper.c | 11 +++++++++-- target/sparc/cpu.c | 2 +- target/sparc/cpu.h | 1 + target/sparc/int32_helper.c | 7 +++++++ target/sparc/int64_helper.c | 7 +++++++ target/tilegx/cpu.c | 9 ++++++++- target/unicore32/cpu.c | 2 +- target/unicore32/cpu.h | 1 + target/unicore32/softmmu.c | 7 +++++++ target/xtensa/cpu.c | 2 +- target/xtensa/cpu.h | 2 +- target/xtensa/exc_helper.c | 11 +++++++++-- 64 files changed, 223 insertions(+), 60 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 80d0e649b2..e661635f06 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -517,9 +517,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, = int *ret) #else if (replay_exception()) { CPUClass *cc =3D CPU_GET_CLASS(cpu); - qemu_mutex_lock_iothread(); cc->do_interrupt(cpu); - qemu_mutex_unlock_iothread(); cpu->exception_index =3D -1; =20 if (unlikely(cpu->singlestep_enabled)) { diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index cb1074e0f9..09677c6c44 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c @@ -217,7 +217,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void = *data) =20 cc->class_by_name =3D alpha_cpu_class_by_name; cc->has_work =3D alpha_cpu_has_work; - cc->do_interrupt =3D alpha_cpu_do_interrupt_locked; + cc->do_interrupt =3D alpha_cpu_do_interrupt; cc->cpu_exec_interrupt =3D alpha_cpu_exec_interrupt; cc->dump_state =3D alpha_cpu_dump_state; cc->set_pc =3D alpha_cpu_set_pc; diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index 4c6753df34..be29bdd530 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -276,7 +276,7 @@ struct AlphaCPU { extern const VMStateDescription vmstate_alpha_cpu; #endif =20 -void alpha_cpu_do_interrupt_locked(CPUState *cpu); +void alpha_cpu_do_interrupt(CPUState *cpu); bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/alpha/helper.c b/target/alpha/helper.c index ff9a2a7765..e497dd269e 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -295,7 +295,7 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int s= ize, } #endif /* USER_ONLY */ =20 -void alpha_cpu_do_interrupt_locked(CPUState *cs) +static void alpha_cpu_do_interrupt_locked(CPUState *cs) { AlphaCPU *cpu =3D ALPHA_CPU(cs); CPUAlphaState *env =3D &cpu->env; @@ -407,6 +407,13 @@ void alpha_cpu_do_interrupt_locked(CPUState *cs) #endif /* !USER_ONLY */ } =20 +void alpha_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + alpha_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { AlphaCPU *cpu =3D ALPHA_CPU(cs); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index d15b459399..12eda7611f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -2224,7 +2224,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void = *data) cc->gdb_read_register =3D arm_cpu_gdb_read_register; cc->gdb_write_register =3D arm_cpu_gdb_write_register; #ifndef CONFIG_USER_ONLY - cc->do_interrupt =3D arm_cpu_do_interrupt_locked; + cc->do_interrupt =3D arm_cpu_do_interrupt; acc->do_interrupt_locked =3D arm_cpu_do_interrupt_locked; cc->get_phys_page_attrs_debug =3D arm_cpu_get_phys_page_attrs_debug; cc->asidx_from_attrs =3D arm_asidx_from_attrs; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 1f522964b5..57b8904dec 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -991,7 +991,9 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz= ); extern const VMStateDescription vmstate_arm_cpu; #endif =20 +void arm_cpu_do_interrupt(CPUState *cpu); void arm_cpu_do_interrupt_locked(CPUState *cpu); +void arm_v7m_cpu_do_interrupt(CPUState *cpu); void arm_v7m_cpu_do_interrupt_locked(CPUState *cpu); bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req); =20 diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index caf0d54c2c..df36cfda76 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -601,7 +601,7 @@ static void arm_v7m_class_init(ObjectClass *oc, void *d= ata) =20 acc->info =3D data; #ifndef CONFIG_USER_ONLY - cc->do_interrupt =3D arm_v7m_cpu_do_interrupt_locked; + cc->do_interrupt =3D arm_cpu_do_interrupt; acc->do_interrupt_locked =3D arm_v7m_cpu_do_interrupt_locked; #endif =20 diff --git a/target/arm/helper.c b/target/arm/helper.c index e07924daf5..f0ab750088 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -9840,6 +9840,14 @@ static void handle_semihosting(CPUState *cs) } #endif =20 +void arm_cpu_do_interrupt(CPUState *cs) +{ + ARMCPUClass *acc =3D ARM_CPU_GET_CLASS(cs); + qemu_mutex_lock_iothread(); + acc->do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + /* Handle a CPU exception for A and R profile CPUs. * Do any appropriate logging, handle PSCI calls, and then hand off * to the AArch64-entry or AArch32-entry function depending on the diff --git a/target/avr/cpu.c b/target/avr/cpu.c index d856069230..5d9c4ad5bf 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c @@ -197,7 +197,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *d= ata) cc->class_by_name =3D avr_cpu_class_by_name; =20 cc->has_work =3D avr_cpu_has_work; - cc->do_interrupt =3D avr_cpu_do_interrupt_locked; + cc->do_interrupt =3D avr_cpu_do_interrupt; cc->cpu_exec_interrupt =3D avr_cpu_exec_interrupt; cc->dump_state =3D avr_cpu_dump_state; cc->set_pc =3D avr_cpu_set_pc; diff --git a/target/avr/cpu.h b/target/avr/cpu.h index 66a26f08ef..d148e8c75a 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -156,7 +156,7 @@ typedef struct AVRCPU { =20 extern const struct VMStateDescription vms_avr_cpu; =20 -void avr_cpu_do_interrupt_locked(CPUState *cpu); +void avr_cpu_do_interrupt(CPUState *cpu); bool avr_cpu_exec_interrupt(CPUState *cpu, int int_req); hwaddr avr_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); int avr_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); diff --git a/target/avr/helper.c b/target/avr/helper.c index 096bc35945..2c8c3af580 100644 --- a/target/avr/helper.c +++ b/target/avr/helper.c @@ -24,17 +24,18 @@ #include "exec/address-spaces.h" #include "exec/helper-proto.h" =20 +static void avr_cpu_do_interrupt_locked(CPUState *cs); + bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { bool ret =3D false; - CPUClass *cc =3D CPU_GET_CLASS(cs); AVRCPU *cpu =3D AVR_CPU(cs); CPUAVRState *env =3D &cpu->env; =20 if (interrupt_request & CPU_INTERRUPT_RESET) { if (cpu_interrupts_enabled(env)) { cs->exception_index =3D EXCP_RESET; - cc->do_interrupt(cs); + avr_cpu_do_interrupt_locked(cs); =20 cs->interrupt_request &=3D ~CPU_INTERRUPT_RESET; =20 @@ -45,7 +46,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_r= equest) if (cpu_interrupts_enabled(env) && env->intsrc !=3D 0) { int index =3D ctz32(env->intsrc); cs->exception_index =3D EXCP_INT(index); - cc->do_interrupt(cs); + avr_cpu_do_interrupt_locked(cs); =20 env->intsrc &=3D env->intsrc - 1; /* clear the interrupt */ cs->interrupt_request &=3D ~CPU_INTERRUPT_HARD; @@ -56,7 +57,7 @@ bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_r= equest) return ret; } =20 -void avr_cpu_do_interrupt_locked(CPUState *cs) +static void avr_cpu_do_interrupt_locked(CPUState *cs) { AVRCPU *cpu =3D AVR_CPU(cs); CPUAVRState *env =3D &cpu->env; @@ -89,6 +90,13 @@ void avr_cpu_do_interrupt_locked(CPUState *cs) cs->exception_index =3D -1; } =20 +void avr_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + avr_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf, int len, bool is_write) { diff --git a/target/cris/cpu.c b/target/cris/cpu.c index 948eeb6260..c3d77c31e8 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -199,7 +199,6 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void= *data) CRISCPUClass *ccc =3D CRIS_CPU_CLASS(oc); =20 ccc->vr =3D 8; - cc->do_interrupt =3D crisv10_cpu_do_interrupt_locked; ccc->do_interrupt_locked =3D crisv10_cpu_do_interrupt_locked; cc->gdb_read_register =3D crisv10_cpu_gdb_read_register; cc->tcg_initialize =3D cris_initialize_crisv10_tcg; @@ -211,7 +210,6 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void= *data) CRISCPUClass *ccc =3D CRIS_CPU_CLASS(oc); =20 ccc->vr =3D 9; - cc->do_interrupt =3D crisv10_cpu_do_interrupt_locked; ccc->do_interrupt_locked =3D crisv10_cpu_do_interrupt_locked; cc->gdb_read_register =3D crisv10_cpu_gdb_read_register; cc->tcg_initialize =3D cris_initialize_crisv10_tcg; @@ -223,7 +221,6 @@ static void crisv10_cpu_class_init(ObjectClass *oc, voi= d *data) CRISCPUClass *ccc =3D CRIS_CPU_CLASS(oc); =20 ccc->vr =3D 10; - cc->do_interrupt =3D crisv10_cpu_do_interrupt_locked; ccc->do_interrupt_locked =3D crisv10_cpu_do_interrupt_locked; cc->gdb_read_register =3D crisv10_cpu_gdb_read_register; cc->tcg_initialize =3D cris_initialize_crisv10_tcg; @@ -235,7 +232,6 @@ static void crisv11_cpu_class_init(ObjectClass *oc, voi= d *data) CRISCPUClass *ccc =3D CRIS_CPU_CLASS(oc); =20 ccc->vr =3D 11; - cc->do_interrupt =3D crisv10_cpu_do_interrupt_locked; ccc->do_interrupt_locked =3D crisv10_cpu_do_interrupt_locked; cc->gdb_read_register =3D crisv10_cpu_gdb_read_register; cc->tcg_initialize =3D cris_initialize_crisv10_tcg; @@ -247,7 +243,6 @@ static void crisv17_cpu_class_init(ObjectClass *oc, voi= d *data) CRISCPUClass *ccc =3D CRIS_CPU_CLASS(oc); =20 ccc->vr =3D 17; - cc->do_interrupt =3D crisv10_cpu_do_interrupt_locked; ccc->do_interrupt_locked =3D crisv10_cpu_do_interrupt_locked; cc->gdb_read_register =3D crisv10_cpu_gdb_read_register; cc->tcg_initialize =3D cris_initialize_crisv10_tcg; @@ -273,7 +268,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *= data) =20 cc->class_by_name =3D cris_cpu_class_by_name; cc->has_work =3D cris_cpu_has_work; - cc->do_interrupt =3D cris_cpu_do_interrupt_locked; + cc->do_interrupt =3D cris_cpu_do_interrupt; ccc->do_interrupt_locked =3D cris_cpu_do_interrupt_locked; cc->cpu_exec_interrupt =3D cris_cpu_exec_interrupt; cc->dump_state =3D cris_cpu_dump_state; diff --git a/target/cris/cpu.h b/target/cris/cpu.h index 597ccd6451..d8ee6b9400 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -187,6 +187,7 @@ struct CRISCPU { extern const VMStateDescription vmstate_cris_cpu; #endif =20 +void cris_cpu_do_interrupt(CPUState *cpu); void cris_cpu_do_interrupt_locked(CPUState *cpu); void crisv10_cpu_do_interrupt_locked(CPUState *cpu); bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req); diff --git a/target/cris/helper.c b/target/cris/helper.c index 3b7ee74813..0e053782ab 100644 --- a/target/cris/helper.c +++ b/target/cris/helper.c @@ -38,6 +38,14 @@ #define D_LOG(...) do { } while (0) #endif =20 +void cris_cpu_do_interrupt(CPUState *cs) +{ + CRISCPUClass *acc =3D CRIS_CPU_GET_CLASS(cs); + qemu_mutex_lock_iothread(); + acc->do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + #if defined(CONFIG_USER_ONLY) =20 void cris_cpu_do_interrupt_locked(CPUState *cs) diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 7241ffbd7f..287055f96e 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c @@ -139,7 +139,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *= data) =20 cc->class_by_name =3D hppa_cpu_class_by_name; cc->has_work =3D hppa_cpu_has_work; - cc->do_interrupt =3D hppa_cpu_do_interrupt_locked; + cc->do_interrupt =3D hppa_cpu_do_interrupt; cc->cpu_exec_interrupt =3D hppa_cpu_exec_interrupt; cc->dump_state =3D hppa_cpu_dump_state; cc->set_pc =3D hppa_cpu_set_pc; diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 7fc7682ca8..801a4fb1ba 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -323,7 +323,7 @@ int cpu_hppa_signal_handler(int host_signum, void *pinf= o, void *puc); hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); -void hppa_cpu_do_interrupt_locked(CPUState *cpu); +void hppa_cpu_do_interrupt(CPUState *cpu); bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req); void hppa_cpu_dump_state(CPUState *cs, FILE *f, int); bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c index 31fce959d6..03cb521a96 100644 --- a/target/hppa/int_helper.c +++ b/target/hppa/int_helper.c @@ -90,7 +90,7 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg va= l) } #endif /* !CONFIG_USER_ONLY */ =20 -void hppa_cpu_do_interrupt_locked(CPUState *cs) +static void hppa_cpu_do_interrupt_locked(CPUState *cs) { HPPACPU *cpu =3D HPPA_CPU(cs); CPUHPPAState *env =3D &cpu->env; @@ -246,6 +246,13 @@ void hppa_cpu_do_interrupt_locked(CPUState *cs) cs->exception_index =3D -1; } =20 +void hppa_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + hppa_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { #ifndef CONFIG_USER_ONLY diff --git a/target/i386/cpu.c b/target/i386/cpu.c index fdb8ae11b6..592aa0baf7 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -7297,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc= , void *data) cc->parse_features =3D x86_cpu_parse_featurestr; cc->has_work =3D x86_cpu_has_work; #ifdef CONFIG_TCG - cc->do_interrupt =3D x86_cpu_do_interrupt_locked; + cc->do_interrupt =3D x86_cpu_do_interrupt; cc->cpu_exec_interrupt =3D x86_cpu_exec_interrupt; #endif cc->dump_state =3D x86_cpu_dump_state; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 8d4dac129b..d784eeaf29 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1770,7 +1770,7 @@ extern VMStateDescription vmstate_x86_cpu; * x86_cpu_do_interrupt: * @cpu: vCPU the interrupt is to be handled by. */ -void x86_cpu_do_interrupt_locked(CPUState *cpu); +void x86_cpu_do_interrupt(CPUState *cpu); bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req); int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request); =20 diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c index 0d8464abec..74484eb175 100644 --- a/target/i386/seg_helper.c +++ b/target/i386/seg_helper.c @@ -1280,7 +1280,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, = int is_int, #endif } =20 -void x86_cpu_do_interrupt_locked(CPUState *cs) +static void x86_cpu_do_interrupt_locked(CPUState *cs) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; @@ -1310,6 +1310,13 @@ void x86_cpu_do_interrupt_locked(CPUState *cs) #endif } =20 +void x86_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + x86_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw) { do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw); diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c index 93da742520..9e7d8ca929 100644 --- a/target/lm32/cpu.c +++ b/target/lm32/cpu.c @@ -222,7 +222,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *= data) =20 cc->class_by_name =3D lm32_cpu_class_by_name; cc->has_work =3D lm32_cpu_has_work; - cc->do_interrupt =3D lm32_cpu_do_interrupt_locked; + cc->do_interrupt =3D lm32_cpu_do_interrupt; cc->cpu_exec_interrupt =3D lm32_cpu_exec_interrupt; cc->dump_state =3D lm32_cpu_dump_state; cc->set_pc =3D lm32_cpu_set_pc; diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h index cd96a2905e..01d408eb55 100644 --- a/target/lm32/cpu.h +++ b/target/lm32/cpu.h @@ -198,7 +198,7 @@ struct LM32CPU { extern const VMStateDescription vmstate_lm32_cpu; #endif =20 -void lm32_cpu_do_interrupt_locked(CPUState *cpu); +void lm32_cpu_do_interrupt(CPUState *cpu); bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req); void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/lm32/helper.c b/target/lm32/helper.c index 8599a59df2..6184e212cf 100644 --- a/target/lm32/helper.c +++ b/target/lm32/helper.c @@ -148,7 +148,7 @@ void lm32_debug_excp_handler(CPUState *cs) } } =20 -void lm32_cpu_do_interrupt_locked(CPUState *cs) +static void lm32_cpu_do_interrupt_locked(CPUState *cs) { LM32CPU *cpu =3D LM32_CPU(cs); CPULM32State *env =3D &cpu->env; @@ -198,6 +198,13 @@ void lm32_cpu_do_interrupt_locked(CPUState *cs) } } =20 +void lm32_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + lm32_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { LM32CPU *cpu =3D LM32_CPU(cs); diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index 6ac0dd87a6..f2585154f5 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -277,7 +277,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *d= ata) =20 cc->class_by_name =3D m68k_cpu_class_by_name; cc->has_work =3D m68k_cpu_has_work; - cc->do_interrupt =3D m68k_cpu_do_interrupt_locked; + cc->do_interrupt =3D m68k_cpu_do_interrupt; cc->cpu_exec_interrupt =3D m68k_cpu_exec_interrupt; cc->dump_state =3D m68k_cpu_dump_state; cc->set_pc =3D m68k_cpu_set_pc; diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 1afbe94570..521ac67cdd 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -164,7 +164,7 @@ struct M68kCPU { }; =20 =20 -void m68k_cpu_do_interrupt_locked(CPUState *cpu); +void m68k_cpu_do_interrupt(CPUState *cpu); bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 8fd6481883..3f0c99124a 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -25,7 +25,7 @@ =20 #if defined(CONFIG_USER_ONLY) =20 -void m68k_cpu_do_interrupt_locked(CPUState *cs) +static void m68k_cpu_do_interrupt_locked(CPUState *cs) { cs->exception_index =3D -1; } @@ -443,7 +443,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_= hw) cf_interrupt_all(env, is_hw); } =20 -void m68k_cpu_do_interrupt_locked(CPUState *cs) +static void m68k_cpu_do_interrupt_locked(CPUState *cs) { M68kCPU *cpu =3D M68K_CPU(cs); CPUM68KState *env =3D &cpu->env; @@ -504,6 +504,13 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr = physaddr, vaddr addr, } #endif =20 +void m68k_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + m68k_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { M68kCPU *cpu =3D M68K_CPU(cs); diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index b19e386bcf..ce70f7d281 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -316,7 +316,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *da= ta) =20 cc->class_by_name =3D mb_cpu_class_by_name; cc->has_work =3D mb_cpu_has_work; - cc->do_interrupt =3D mb_cpu_do_interrupt_locked; + cc->do_interrupt =3D mb_cpu_do_interrupt; cc->cpu_exec_interrupt =3D mb_cpu_exec_interrupt; cc->dump_state =3D mb_cpu_dump_state; cc->set_pc =3D mb_cpu_set_pc; diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 7617565a0c..a31134b65c 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -315,7 +315,7 @@ struct MicroBlazeCPU { }; =20 =20 -void mb_cpu_do_interrupt_locked(CPUState *cs); +void mb_cpu_do_interrupt(CPUState *cs); bool mb_cpu_exec_interrupt(CPUState *cs, int int_req); void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index 263cdf59be..f241587b40 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -28,7 +28,7 @@ =20 #if defined(CONFIG_USER_ONLY) =20 -void mb_cpu_do_interrupt_locked(CPUState *cs) +static void mb_cpu_do_interrupt_locked(CPUState *cs) { MicroBlazeCPU *cpu =3D MICROBLAZE_CPU(cs); CPUMBState *env =3D &cpu->env; @@ -108,7 +108,7 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int s= ize, cpu_loop_exit_restore(cs, retaddr); } =20 -void mb_cpu_do_interrupt_locked(CPUState *cs) +static void mb_cpu_do_interrupt_locked(CPUState *cs) { MicroBlazeCPU *cpu =3D MICROBLAZE_CPU(cs); CPUMBState *env =3D &cpu->env; @@ -287,6 +287,13 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr = addr) } #endif =20 +void mb_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + mb_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { MicroBlazeCPU *cpu =3D MICROBLAZE_CPU(cs); diff --git a/target/mips/cpu.c b/target/mips/cpu.c index c616a0ef5a..ec9dde5100 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -196,7 +196,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *d= ata) =20 cc->class_by_name =3D mips_cpu_class_by_name; cc->has_work_with_iothread_lock =3D mips_cpu_has_work; - cc->do_interrupt =3D mips_cpu_do_interrupt_locked; + cc->do_interrupt =3D mips_cpu_do_interrupt; cc->cpu_exec_interrupt =3D mips_cpu_exec_interrupt; cc->dump_state =3D mips_cpu_dump_state; cc->set_pc =3D mips_cpu_set_pc; diff --git a/target/mips/helper.c b/target/mips/helper.c index a85c4057d0..3941392b95 100644 --- a/target/mips/helper.c +++ b/target/mips/helper.c @@ -1083,7 +1083,7 @@ static inline void set_badinstr_registers(CPUMIPSStat= e *env) } #endif =20 -void mips_cpu_do_interrupt_locked(CPUState *cs) +static void mips_cpu_do_interrupt_locked(CPUState *cs) { #if !defined(CONFIG_USER_ONLY) MIPSCPU *cpu =3D MIPS_CPU(cs); @@ -1398,6 +1398,13 @@ void mips_cpu_do_interrupt_locked(CPUState *cs) cs->exception_index =3D EXCP_NONE; } =20 +void mips_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + mips_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { if (interrupt_request & CPU_INTERRUPT_HARD) { diff --git a/target/mips/internal.h b/target/mips/internal.h index fb0181c095..7f159a9230 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -80,7 +80,7 @@ enum CPUMIPSMSADataFormat { DF_DOUBLE }; =20 -void mips_cpu_do_interrupt_locked(CPUState *cpu); +void mips_cpu_do_interrupt(CPUState *cpu); bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req); void mips_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c index cc813181a4..7116b3f230 100644 --- a/target/nios2/cpu.c +++ b/target/nios2/cpu.c @@ -192,7 +192,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void = *data) =20 cc->class_by_name =3D nios2_cpu_class_by_name; cc->has_work =3D nios2_cpu_has_work; - cc->do_interrupt =3D nios2_cpu_do_interrupt_locked; + cc->do_interrupt =3D nios2_cpu_do_interrupt; cc->cpu_exec_interrupt =3D nios2_cpu_exec_interrupt; cc->dump_state =3D nios2_cpu_dump_state; cc->set_pc =3D nios2_cpu_set_pc; diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h index dcf1715092..6fa60b1399 100644 --- a/target/nios2/cpu.h +++ b/target/nios2/cpu.h @@ -195,6 +195,7 @@ typedef struct Nios2CPU { =20 =20 void nios2_tcg_init(void); +void nios2_cpu_do_interrupt(CPUState *cs); void nios2_cpu_do_interrupt_locked(CPUState *cs); int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc); void dump_mmu(CPUNios2State *env); diff --git a/target/nios2/helper.c b/target/nios2/helper.c index 25c6c6d4d8..c81aa073f4 100644 --- a/target/nios2/helper.c +++ b/target/nios2/helper.c @@ -312,3 +312,12 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, i= nt size, cpu_loop_exit_restore(cs, retaddr); } #endif /* !CONFIG_USER_ONLY */ + +void nios2_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + nios2_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + + diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index e428946dc2..fd2da39124 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -154,7 +154,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, vo= id *data) =20 cc->class_by_name =3D openrisc_cpu_class_by_name; cc->has_work =3D openrisc_cpu_has_work; - cc->do_interrupt =3D openrisc_cpu_do_interrupt_locked; + cc->do_interrupt =3D openrisc_cpu_do_interrupt; cc->cpu_exec_interrupt =3D openrisc_cpu_exec_interrupt; cc->dump_state =3D openrisc_cpu_dump_state; cc->set_pc =3D openrisc_cpu_set_pc; diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index e77f075cd9..f37a52e153 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -316,7 +316,7 @@ typedef struct OpenRISCCPU { =20 =20 void cpu_openrisc_list(void); -void openrisc_cpu_do_interrupt_locked(CPUState *cpu); +void openrisc_cpu_do_interrupt(CPUState *cpu); bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/openrisc/interrupt.c b/target/openrisc/interrupt.c index f95289444f..a5ca3ece78 100644 --- a/target/openrisc/interrupt.c +++ b/target/openrisc/interrupt.c @@ -26,7 +26,7 @@ #include "hw/loader.h" #endif =20 -void openrisc_cpu_do_interrupt_locked(CPUState *cs) +static void openrisc_cpu_do_interrupt_locked(CPUState *cs) { #ifndef CONFIG_USER_ONLY OpenRISCCPU *cpu =3D OPENRISC_CPU(cs); @@ -101,6 +101,13 @@ void openrisc_cpu_do_interrupt_locked(CPUState *cs) cs->exception_index =3D -1; } =20 +void openrisc_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + openrisc_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool openrisc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { OpenRISCCPU *cpu =3D OPENRISC_CPU(cs); diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ed297acdb4..2569d43e59 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1231,6 +1231,7 @@ struct PPCVirtualHypervisorClass { TYPE_PPC_VIRTUAL_HYPERVISOR) #endif /* CONFIG_USER_ONLY */ =20 +void ppc_cpu_do_interrupt(CPUState *cpu); void ppc_cpu_do_interrupt_locked(CPUState *cpu); bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index fe9b122fd0..2cb1aaa296 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1428,3 +1428,10 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr= vaddr, env->error_code =3D insn & 0x03FF0000; cpu_loop_exit(cs); } + +void ppc_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + ppc_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.in= c.c index 653b04aef6..27ae7fa195 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -10885,7 +10885,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, voi= d *data) pcc->parent_parse_features =3D cc->parse_features; cc->parse_features =3D ppc_cpu_parse_featurestr; cc->has_work_with_iothread_lock =3D ppc_cpu_has_work; - cc->do_interrupt =3D ppc_cpu_do_interrupt_locked; + cc->do_interrupt =3D ppc_cpu_do_interrupt; cc->cpu_exec_interrupt =3D ppc_cpu_exec_interrupt; cc->dump_state =3D ppc_cpu_dump_state; cc->dump_statistics =3D ppc_cpu_dump_statistics; diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 833e6d4f1e..832171c360 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -537,7 +537,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *= data) =20 cc->class_by_name =3D riscv_cpu_class_by_name; cc->has_work_with_iothread_lock =3D riscv_cpu_has_work; - cc->do_interrupt =3D riscv_cpu_do_interrupt_locked; + cc->do_interrupt =3D riscv_cpu_do_interrupt; cc->cpu_exec_interrupt =3D riscv_cpu_exec_interrupt; cc->dump_state =3D riscv_cpu_dump_state; cc->set_pc =3D riscv_cpu_set_pc; diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 372005b79c..a804a5d0ba 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -312,7 +312,7 @@ extern const char * const riscv_fpr_regnames[]; extern const char * const riscv_excp_names[]; extern const char * const riscv_intr_names[]; =20 -void riscv_cpu_do_interrupt_locked(CPUState *cpu); +void riscv_cpu_do_interrupt(CPUState *cpu); int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request); diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 477cf66b66..2c8ee8ca2b 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -25,6 +25,8 @@ #include "tcg/tcg-op.h" #include "trace.h" =20 +static void riscv_cpu_do_interrupt_locked(CPUState *cs); + int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) { #ifdef CONFIG_USER_ONLY @@ -814,13 +816,20 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, = int size, #endif } =20 +void riscv_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + riscv_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + /* * Handle Traps * * Adapted from Spike's processor_t::take_trap. * */ -void riscv_cpu_do_interrupt_locked(CPUState *cs) +static void riscv_cpu_do_interrupt_locked(CPUState *cs) { #if !defined(CONFIG_USER_ONLY) =20 diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 51e10da7cc..219e05397b 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c @@ -185,7 +185,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void = *data) =20 cc->class_by_name =3D rx_cpu_class_by_name; cc->has_work =3D rx_cpu_has_work; - cc->do_interrupt =3D rx_cpu_do_interrupt_locked; + cc->do_interrupt =3D rx_cpu_do_interrupt; cc->cpu_exec_interrupt =3D rx_cpu_exec_interrupt; cc->dump_state =3D rx_cpu_dump_state; cc->set_pc =3D rx_cpu_set_pc; diff --git a/target/rx/cpu.h b/target/rx/cpu.h index d188e7d43f..ec085d0386 100644 --- a/target/rx/cpu.h +++ b/target/rx/cpu.h @@ -125,6 +125,7 @@ typedef RXCPU ArchCPU; #define CPU_RESOLVING_TYPE TYPE_RX_CPU =20 const char *rx_crname(uint8_t cr); +void rx_cpu_do_interrupt(CPUState *cpu); void rx_cpu_do_interrupt_locked(CPUState *cpu); bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req); void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags); diff --git a/target/rx/helper.c b/target/rx/helper.c index 332f89435a..8c0512b62a 100644 --- a/target/rx/helper.c +++ b/target/rx/helper.c @@ -119,6 +119,13 @@ void rx_cpu_do_interrupt_locked(CPUState *cs) env->regs[0] =3D env->isp; } =20 +void rx_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + rx_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { RXCPU *cpu =3D RXCPU(cs); diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index eb23d64f36..4d0d323cf9 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -493,7 +493,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *= data) cc->class_by_name =3D s390_cpu_class_by_name, cc->has_work_with_iothread_lock =3D s390_cpu_has_work; #ifdef CONFIG_TCG - cc->do_interrupt =3D s390_cpu_do_interrupt_locked; + cc->do_interrupt =3D s390_cpu_do_interrupt; #endif cc->dump_state =3D s390_cpu_dump_state; cc->set_pc =3D s390_cpu_set_pc; diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c index a663127f17..a020db1725 100644 --- a/target/s390x/excp_helper.c +++ b/target/s390x/excp_helper.c @@ -611,3 +611,10 @@ void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr= addr, } =20 #endif /* CONFIG_USER_ONLY */ + +void s390_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + s390_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} diff --git a/target/s390x/internal.h b/target/s390x/internal.h index 6ab0fb481a..b4660ad255 100644 --- a/target/s390x/internal.h +++ b/target/s390x/internal.h @@ -268,6 +268,7 @@ ObjectClass *s390_cpu_class_by_name(const char *name); =20 /* excp_helper.c */ void s390x_cpu_debug_excp_handler(CPUState *cs); +void s390_cpu_do_interrupt(CPUState *cpu); void s390_cpu_do_interrupt_locked(CPUState *cpu); bool s390_cpu_exec_interrupt(CPUState *cpu, int int_req); bool s390_cpu_tlb_fill(CPUState *cs, vaddr address, int size, diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 5e5921a220..18f3448183 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -218,7 +218,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void= *data) =20 cc->class_by_name =3D superh_cpu_class_by_name; cc->has_work =3D superh_cpu_has_work; - cc->do_interrupt =3D superh_cpu_do_interrupt_locked; + cc->do_interrupt =3D superh_cpu_do_interrupt; cc->cpu_exec_interrupt =3D superh_cpu_exec_interrupt; cc->dump_state =3D superh_cpu_dump_state; cc->set_pc =3D superh_cpu_set_pc; diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 2ae3dd132b..dbe58c7888 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -204,7 +204,7 @@ struct SuperHCPU { }; =20 =20 -void superh_cpu_do_interrupt_locked(CPUState *cpu); +void superh_cpu_do_interrupt(CPUState *cpu); bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req); void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/sh4/helper.c b/target/sh4/helper.c index 2d61f65d50..471650b622 100644 --- a/target/sh4/helper.c +++ b/target/sh4/helper.c @@ -45,7 +45,7 @@ =20 #if defined(CONFIG_USER_ONLY) =20 -void superh_cpu_do_interrupt_locked(CPUState *cs) +static void superh_cpu_do_interrupt_locked(CPUState *cs) { cs->exception_index =3D -1; } @@ -58,7 +58,7 @@ int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr) =20 #else /* !CONFIG_USER_ONLY */ =20 -void superh_cpu_do_interrupt_locked(CPUState *cs) +static void superh_cpu_do_interrupt_locked(CPUState *cs) { SuperHCPU *cpu =3D SUPERH_CPU(cs); CPUSH4State *env =3D &cpu->env; @@ -782,6 +782,13 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong = addr) =20 #endif =20 +void superh_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + superh_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { if (interrupt_request & CPU_INTERRUPT_HARD) { diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 4c8842adcf..1c26bbd59b 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c @@ -863,7 +863,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void = *data) cc->class_by_name =3D sparc_cpu_class_by_name; cc->parse_features =3D sparc_cpu_parse_features; cc->has_work_with_iothread_lock =3D sparc_cpu_has_work; - cc->do_interrupt =3D sparc_cpu_do_interrupt_locked; + cc->do_interrupt =3D sparc_cpu_do_interrupt; cc->cpu_exec_interrupt =3D sparc_cpu_exec_interrupt; cc->dump_state =3D sparc_cpu_dump_state; #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index 3563e65d73..ec8684ec93 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -568,6 +568,7 @@ struct SPARCCPU { extern const VMStateDescription vmstate_sparc_cpu; #endif =20 +void sparc_cpu_do_interrupt(CPUState *cpu); void sparc_cpu_do_interrupt_locked(CPUState *cpu); void sparc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/sparc/int32_helper.c b/target/sparc/int32_helper.c index 90f4aa4a78..7a1f15b06c 100644 --- a/target/sparc/int32_helper.c +++ b/target/sparc/int32_helper.c @@ -138,6 +138,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs) #endif } =20 +void sparc_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + sparc_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + #if !defined(CONFIG_USER_ONLY) static void leon3_cache_control_int(CPUSPARCState *env) { diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c index b81b4abaa8..aa3d9aa585 100644 --- a/target/sparc/int64_helper.c +++ b/target/sparc/int64_helper.c @@ -198,6 +198,13 @@ void sparc_cpu_do_interrupt_locked(CPUState *cs) cs->exception_index =3D -1; } =20 +void sparc_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + sparc_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + trap_state *cpu_tsptr(CPUSPARCState* env) { return &env->ts[env->tl & MAXTL_MASK]; diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c index a2ff335977..a450dc63a3 100644 --- a/target/tilegx/cpu.c +++ b/target/tilegx/cpu.c @@ -125,6 +125,13 @@ static bool tilegx_cpu_tlb_fill(CPUState *cs, vaddr ad= dress, int size, cpu_loop_exit_restore(cs, retaddr); } =20 +static void tilegx_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + tilegx_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { if (interrupt_request & CPU_INTERRUPT_HARD) { @@ -147,7 +154,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void= *data) =20 cc->class_by_name =3D tilegx_cpu_class_by_name; cc->has_work =3D tilegx_cpu_has_work; - cc->do_interrupt =3D tilegx_cpu_do_interrupt_locked; + cc->do_interrupt =3D tilegx_cpu_do_interrupt; cc->cpu_exec_interrupt =3D tilegx_cpu_exec_interrupt; cc->dump_state =3D tilegx_cpu_dump_state; cc->set_pc =3D tilegx_cpu_set_pc; diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c index a96077d666..06bf4b4b63 100644 --- a/target/unicore32/cpu.c +++ b/target/unicore32/cpu.c @@ -131,7 +131,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *= data) =20 cc->class_by_name =3D uc32_cpu_class_by_name; cc->has_work =3D uc32_cpu_has_work; - cc->do_interrupt =3D uc32_cpu_do_interrupt_locked; + cc->do_interrupt =3D uc32_cpu_do_interrupt; cc->cpu_exec_interrupt =3D uc32_cpu_exec_interrupt; cc->dump_state =3D uc32_cpu_dump_state; cc->set_pc =3D uc32_cpu_set_pc; diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h index d948392ff3..9453b5d7b3 100644 --- a/target/unicore32/cpu.h +++ b/target/unicore32/cpu.h @@ -75,6 +75,7 @@ struct UniCore32CPU { }; =20 =20 +void uc32_cpu_do_interrupt(CPUState *cpu); void uc32_cpu_do_interrupt_locked(CPUState *cpu); bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req); void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags); diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c index a12526a8ca..7fb28f3c12 100644 --- a/target/unicore32/softmmu.c +++ b/target/unicore32/softmmu.c @@ -120,6 +120,13 @@ void uc32_cpu_do_interrupt_locked(CPUState *cs) cpu_interrupt_request_or(cs, CPU_INTERRUPT_EXITTB); } =20 +void uc32_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + uc32_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address, int access_type, int is_user, uint32_t *phys_ptr, int *prot, target_ulong *page_size) diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 7962bc66a8..0f96483563 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -190,7 +190,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void= *data) =20 cc->class_by_name =3D xtensa_cpu_class_by_name; cc->has_work_with_iothread_lock =3D xtensa_cpu_has_work; - cc->do_interrupt =3D xtensa_cpu_do_interrupt_locked; + cc->do_interrupt =3D xtensa_cpu_do_interrupt; cc->cpu_exec_interrupt =3D xtensa_cpu_exec_interrupt; cc->dump_state =3D xtensa_cpu_dump_state; cc->set_pc =3D xtensa_cpu_set_pc; diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index c02f531b64..32749378bf 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -563,7 +563,7 @@ struct XtensaCPU { bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); -void xtensa_cpu_do_interrupt_locked(CPUState *cpu); +void xtensa_cpu_do_interrupt(CPUState *cpu); bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request); void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr= addr, unsigned size, MMUAccessType access_= type, diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c index 10d4762f36..822ed7aad8 100644 --- a/target/xtensa/exc_helper.c +++ b/target/xtensa/exc_helper.c @@ -195,7 +195,7 @@ static void handle_interrupt(CPUXtensaState *env) } =20 /* Called from cpu_handle_interrupt with BQL held */ -void xtensa_cpu_do_interrupt_locked(CPUState *cs) +static void xtensa_cpu_do_interrupt_locked(CPUState *cs) { XtensaCPU *cpu =3D XTENSA_CPU(cs); CPUXtensaState *env =3D &cpu->env; @@ -254,11 +254,18 @@ void xtensa_cpu_do_interrupt_locked(CPUState *cs) check_interrupts(env); } #else -void xtensa_cpu_do_interrupt_locked(CPUState *cs) +static void xtensa_cpu_do_interrupt_locked(CPUState *cs) { } #endif =20 +void xtensa_cpu_do_interrupt(CPUState *cs) +{ + qemu_mutex_lock_iothread(); + xtensa_cpu_do_interrupt_locked(cs); + qemu_mutex_unlock_iothread(); +} + bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { if (interrupt_request & CPU_INTERRUPT_HARD) { --=20 2.17.1