From nobody Tue Nov 4 06:39:53 2025 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.zohomail.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 1505240530506799.9490653292537; Tue, 12 Sep 2017 11:22:10 -0700 (PDT) Received: from localhost ([::1]:37991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpp3-0002UB-Ch for importer@patchew.org; Tue, 12 Sep 2017 14:22:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph9-0003bn-Jz for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:14:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph8-0006Wg-54 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:59 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph4-0006QF-4d; Tue, 12 Sep 2017 14:13:54 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph2-0001BU-I3; Tue, 12 Sep 2017 19:13:52 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:06 +0100 Message-Id: <1505240046-11454-20-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 19/19] nvic: Support banked exceptions in acknowledge and complete 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: patches@linaro.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" Update armv7m_nvic_acknowledge_irq() and armv7m_nvic_complete_irq() to handle banked exceptions: * acknowledge needs to use the correct vector, which may be in sec_vectors[] * acknowledge needs to return to its caller whether the exception should be taken to secure or non-secure state * complete needs its caller to tell it whether the exception being completed is a secure one or not Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpu.h | 15 +++++++++++++-- hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++++------ target/arm/helper.c | 8 +++++--- hw/intc/trace-events | 4 ++-- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 02be3ca..9c336bc 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1476,18 +1476,29 @@ static inline bool armv7m_nvic_can_take_pending_exc= eption(void *opaque) * of architecturally banked exceptions. */ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure); -void armv7m_nvic_acknowledge_irq(void *opaque); +/** + * armv7m_nvic_acknowledge_irq: make highest priority pending exception ac= tive + * @opaque: the NVIC + * + * Move the current highest priority pending exception from the pending + * state to the active state, and update v7m.exception to indicate that + * it is the exception currently being handled. + * + * Returns: true if exception should be taken to Secure state, false for NS + */ +bool armv7m_nvic_acknowledge_irq(void *opaque); /** * armv7m_nvic_complete_irq: complete specified interrupt or exception * @opaque: the NVIC * @irq: the exception number to complete + * @secure: true if this exception was secure * * Returns: -1 if the irq was not active * 1 if completing this irq brought us back to base (no active i= rqs) * 0 if there is still an irq active after this one was completed * (Ignoring -1, this is the same as the RETTOBASE value before completion= .) */ -int armv7m_nvic_complete_irq(void *opaque, int irq); +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure); /** * armv7m_nvic_raw_execution_priority: return the raw execution priority * @opaque: the NVIC diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 9613990..078532a 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -586,24 +586,32 @@ void armv7m_nvic_set_pending(void *opaque, int irq, b= ool secure) } =20 /* Make pending IRQ active. */ -void armv7m_nvic_acknowledge_irq(void *opaque) +bool armv7m_nvic_acknowledge_irq(void *opaque) { NVICState *s =3D (NVICState *)opaque; CPUARMState *env =3D &s->cpu->env; const int pending =3D s->vectpending; const int running =3D nvic_exec_prio(s); VecInfo *vec; + bool targets_secure; =20 assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); =20 - vec =3D &s->vectors[pending]; + if (s->vectpending_is_s_banked) { + vec =3D &s->sec_vectors[pending]; + targets_secure =3D true; + } else { + vec =3D &s->vectors[pending]; + targets_secure =3D !exc_is_banked(s->vectpending) && + exc_targets_secure(s, s->vectpending); + } =20 assert(vec->enabled); assert(vec->pending); =20 assert(s->vectpending_prio < running); =20 - trace_nvic_acknowledge_irq(pending, s->vectpending_prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secur= e); =20 vec->active =3D 1; vec->pending =3D 0; @@ -611,9 +619,11 @@ void armv7m_nvic_acknowledge_irq(void *opaque) env->v7m.exception =3D s->vectpending; =20 nvic_irq_update(s); + + return targets_secure; } =20 -int armv7m_nvic_complete_irq(void *opaque, int irq) +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure) { NVICState *s =3D (NVICState *)opaque; VecInfo *vec; @@ -621,9 +631,13 @@ int armv7m_nvic_complete_irq(void *opaque, int irq) =20 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); =20 - vec =3D &s->vectors[irq]; + if (secure && exc_is_banked(irq)) { + vec =3D &s->sec_vectors[irq]; + } else { + vec =3D &s->vectors[irq]; + } =20 - trace_nvic_complete_irq(irq); + trace_nvic_complete_irq(irq, secure); =20 if (!vec->active) { /* Tell the caller this was an illegal exception return */ diff --git a/target/arm/helper.c b/target/arm/helper.c index b64acd8..8be78ea 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6218,6 +6218,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) bool return_to_sp_process =3D false; bool return_to_handler =3D false; bool rettobase =3D false; + bool exc_secure =3D false; =20 /* We can only get here from an EXCP_EXCEPTION_EXIT, and * gen_bx_excret() enforces the architectural rule @@ -6256,16 +6257,17 @@ static void do_v7m_exception_exit(ARMCPU *cpu) * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.) */ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { - int es =3D excret & R_V7M_EXCRET_ES_MASK; + exc_secure =3D excret & R_V7M_EXCRET_ES_MASK; if (armv7m_nvic_raw_execution_priority(env->nvic) >=3D 0) { - env->v7m.faultmask[es] =3D 0; + env->v7m.faultmask[exc_secure] =3D 0; } } else { env->v7m.faultmask[M_REG_NS] =3D 0; } } =20 - switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) { + switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception, + exc_secure)) { case -1: /* attempt to exit an exception that isn't active */ ufault =3D true; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 29bd308..b86f242 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -176,8 +176,8 @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d= to HardFault: disabled" nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending= irq %d secure-bank %d (enabled: %d priority %d)" nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pen= ding irq %d secure-bank %d (enabled: %d priority %d)" nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than= vectpending: setting irq line to 1" -nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now acti= ve (prio %d)" -nvic_complete_irq(int irq) "NVIC complete IRQ %d" +nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowl= edge IRQ: %d now active (prio %d targets_secure %d)" +nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)" nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to = %d" nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysre= g read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysr= eg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" --=20 2.7.4