From nobody Wed Apr 9 03:25:12 2025 Return-Path: qemu-devel-bounces+famz=redhat.com@nongnu.org Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO zmta03.collab.prod.int.phx2.redhat.com) (10.5.81.10) by zmail26.collab.prod.int.phx2.redhat.com with LMTP; Mon, 4 Sep 2017 08:51:25 -0400 (EDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 40D2145005 for ; Mon, 4 Sep 2017 08:51:25 -0400 (EDT) Received: by smtp.corp.redhat.com (Postfix) id 3C04682080; Mon, 4 Sep 2017 12:51:25 +0000 (UTC) Delivered-To: famz@redhat.com Received: from mx1.redhat.com (ext-mx02.extmail.prod.ext.phx2.redhat.com [10.5.110.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3133D82086 for ; Mon, 4 Sep 2017 12:51:23 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 150D47DD14 for ; Mon, 4 Sep 2017 12:51:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 150D47DD14 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=qemu-devel-bounces+famz=redhat.com@nongnu.org DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 150D47DD14 Received: from localhost ([::1]:59656 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqqX-0006U2-6y for famz@redhat.com; Mon, 04 Sep 2017 08:51:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52894) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqSh-0005Dc-Dx for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1doqST-0004xP-OB for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:43 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37134) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1doqST-0004wD-F0 for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:29 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1doqSS-0005c3-2v for qemu-devel@nongnu.org; Mon, 04 Sep 2017 13:26:28 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 4 Sep 2017 13:26:01 +0100 Message-Id: <1504527967-29248-31-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1504527967-29248-1-git-send-email-peter.maydell@linaro.org> References: <1504527967-29248-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] [PULL 30/36] target/arm: Factor out fault delivery code 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: , Errors-To: qemu-devel-bounces+famz=redhat.com@nongnu.org Sender: "Qemu-devel" X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 205 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 04 Sep 2017 12:51:22 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 04 Sep 2017 12:51:22 +0000 (UTC) for IP:'208.118.235.17' DOMAIN:'lists.gnu.org' HELO:'lists.gnu.org' FROM:'redhat.com@nongnu.org' RCPT:'' X-RedHat-Spam-Score: -5.02 (HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_PASS) 208.118.235.17 lists.gnu.org 208.118.235.17 lists.gnu.org X-Scanned-By: MIMEDefang 2.78 on 10.5.110.26 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Content-Length: 6862 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We currently have some similar code in tlb_fill() and in arm_cpu_do_unaligned_access() for delivering a data abort or prefetch abort. We're also going to want to do the same thing to handle external aborts. Factor out the common code into a new function deliver_fault(). Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Acked-by: Edgar E. Iglesias --- target/arm/op_helper.c | 110 +++++++++++++++++++++++++--------------------= ---- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 5a94a5f..6114597 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -115,6 +115,51 @@ static inline uint32_t merge_syn_data_abort(uint32_t t= emplate_syn, return syn; } =20 +static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_ty= pe, + uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi) +{ + CPUARMState *env =3D &cpu->env; + int target_el; + bool same_el; + uint32_t syn, exc; + + target_el =3D exception_target_el(env); + if (fi->stage2) { + target_el =3D 2; + env->cp15.hpfar_el2 =3D extract64(fi->s2addr, 12, 47) << 4; + } + same_el =3D (arm_current_el(env) =3D=3D target_el); + + if (fsc =3D=3D 0x3f) { + /* Caller doesn't have a long-format fault status code. This + * should only happen if this fault will never actually be reported + * to an EL that uses a syndrome register. Check that here. + * 0x3f is a (currently) reserved FSC code, in case the constructed + * syndrome does leak into the guest somehow. + */ + assert(target_el !=3D 2 && !arm_el_is_aa64(env, target_el)); + } + + if (access_type =3D=3D MMU_INST_FETCH) { + syn =3D syn_insn_abort(same_el, 0, fi->s1ptw, fsc); + exc =3D EXCP_PREFETCH_ABORT; + } else { + syn =3D merge_syn_data_abort(env->exception.syndrome, target_el, + same_el, fi->s1ptw, + access_type =3D=3D MMU_DATA_STORE, + fsc); + if (access_type =3D=3D MMU_DATA_STORE + && arm_feature(env, ARM_FEATURE_V6)) { + fsr |=3D (1 << 11); + } + exc =3D EXCP_DATA_ABORT; + } + + env->exception.vaddress =3D addr; + env->exception.fsr =3D fsr; + raise_exception(env, exc, syn, target_el); +} + /* try to fill the TLB and return an exception if error. If retaddr is * NULL, it means that the function was called in C code (i.e. not * from generated code or from helper.c) @@ -129,23 +174,13 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAcc= essType access_type, ret =3D arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi); if (unlikely(ret)) { ARMCPU *cpu =3D ARM_CPU(cs); - CPUARMState *env =3D &cpu->env; - uint32_t syn, exc, fsc; - unsigned int target_el; - bool same_el; + uint32_t fsc; =20 if (retaddr) { /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr); } =20 - target_el =3D exception_target_el(env); - if (fi.stage2) { - target_el =3D 2; - env->cp15.hpfar_el2 =3D extract64(fi.s2addr, 12, 47) << 4; - } - same_el =3D arm_current_el(env) =3D=3D target_el; - if (fsr & (1 << 9)) { /* LPAE format fault status register : bottom 6 bits are * status code in the same form as needed for syndrome @@ -153,34 +188,15 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAcc= essType access_type, fsc =3D extract32(fsr, 0, 6); } else { /* Short format FSR : this fault will never actually be report= ed - * to an EL that uses a syndrome register. Check that here, - * and use a (currently) reserved FSR code in case the constru= cted - * syndrome does leak into the guest somehow. + * to an EL that uses a syndrome register. Use a (currently) + * reserved FSR code in case the constructed syndrome does leak + * into the guest somehow. deliver_fault will assert that + * we don't target an EL using the syndrome. */ - assert(target_el !=3D 2 && !arm_el_is_aa64(env, target_el)); fsc =3D 0x3f; } =20 - /* For insn and data aborts we assume there is no instruction synd= rome - * information; this is always true for exceptions reported to EL1. - */ - if (access_type =3D=3D MMU_INST_FETCH) { - syn =3D syn_insn_abort(same_el, 0, fi.s1ptw, fsc); - exc =3D EXCP_PREFETCH_ABORT; - } else { - syn =3D merge_syn_data_abort(env->exception.syndrome, target_e= l, - same_el, fi.s1ptw, - access_type =3D=3D MMU_DATA_STORE, = fsc); - if (access_type =3D=3D MMU_DATA_STORE - && arm_feature(env, ARM_FEATURE_V6)) { - fsr |=3D (1 << 11); - } - exc =3D EXCP_DATA_ABORT; - } - - env->exception.vaddress =3D addr; - env->exception.fsr =3D fsr; - raise_exception(env, exc, syn, target_el); + deliver_fault(cpu, addr, access_type, fsr, fsc, &fi); } } =20 @@ -191,9 +207,8 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr va= ddr, { ARMCPU *cpu =3D ARM_CPU(cs); CPUARMState *env =3D &cpu->env; - int target_el; - bool same_el; - uint32_t syn; + uint32_t fsr, fsc; + ARMMMUFaultInfo fi =3D {}; ARMMMUIdx arm_mmu_idx =3D core_to_arm_mmu_idx(env, mmu_idx); =20 if (retaddr) { @@ -201,28 +216,17 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr = vaddr, cpu_restore_state(cs, retaddr); } =20 - target_el =3D exception_target_el(env); - same_el =3D (arm_current_el(env) =3D=3D target_el); - - env->exception.vaddress =3D vaddr; - /* the DFSR for an alignment fault depends on whether we're using * the LPAE long descriptor format, or the short descriptor format */ if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) { - env->exception.fsr =3D (1 << 9) | 0x21; + fsr =3D (1 << 9) | 0x21; } else { - env->exception.fsr =3D 0x1; - } - - if (access_type =3D=3D MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_= V6)) { - env->exception.fsr |=3D (1 << 11); + fsr =3D 0x1; } + fsc =3D 0x21; =20 - syn =3D merge_syn_data_abort(env->exception.syndrome, target_el, - same_el, 0, access_type =3D=3D MMU_DATA_STO= RE, - 0x21); - raise_exception(env, EXCP_DATA_ABORT, syn, target_el); + deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi); } =20 #endif /* !defined(CONFIG_USER_ONLY) */ --=20 2.7.4