From patchwork Mon Sep 4 12:26:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 111584 Delivered-To: patch@linaro.org Received: by 10.140.94.166 with SMTP id g35csp1486266qge; Mon, 4 Sep 2017 05:50:39 -0700 (PDT) X-Google-Smtp-Source: ADKCNb5XjC/WRgNSzZ1OK5J2GRNCh5DiOPcTh847yeCvokzJa+UA36rbTf89aUHNDsG7AxKitYa+ X-Received: by 10.55.122.7 with SMTP id v7mr627246qkc.86.1504529439741; Mon, 04 Sep 2017 05:50:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504529439; cv=none; d=google.com; s=arc-20160816; b=fr23cV3RtxU8SVB+2vgI1U6Hf/Gfr/BHs5haoo73jQ0dYxLNOtB6utVYxR7MRmjvOk ijNrI3IzyYVIXqNthO5dFedkSTAMWkGcvWaDGAUVkZzdXTAzYWqqUpACF2pylL7rOyt1 /sSTIegYWa3La8milWdsNFKGhG7PsXryU61YxChSy3UNslu5pfrCLkbEukcd3T2NNqKu RJwPQ+xyz9ggUJyP+y7+dXgv09Opk58Hdgd9UuUcR+8ojubvuWLJkr4BZuIVr14RBs97 e2qNZtSmDuIZFmEUl9powa0c21ssVkjlK/QFnLkp6aweeL9Cqy+7oHjefKACc+D9Wseg LCyw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=q5tdh4HG9MDhijCpLMuDgQLaA9YXIz16bvm7gfG9Nj8=; b=gvbpTJdctuh46t8leSu7yQ6VCDTMJIKQRPGoP27rU4PtSxlyWvDmRWMdLV1QNYZ5Nk Uj4zsVXOoBxEEdJ1wrWBe6HFp9CL7e2RboU9DnJhmvZd8ejy//HOC6bG5KDCsHVguH8u EOSaRaFQSCPdsUap/jujlkJbmW3Ws6sEYuI5vESm1zVilI22HT71qHBhujpAtSf9vEwF UkQQVmyvBJJMJKnJ0+YsWDEz70NxO/qD4r2pwb7r112FjWCW2OsfqwBB+dFbHxqB8tTV ohKBsMM74sux/2eGItNUJZoUMuFrn2R5m2RzDNIrTvGOVI5slYGmgEsToZT1emwRP7P3 VphQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id y1si4701502qtj.272.2017.09.04.05.50.39 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 04 Sep 2017 05:50:39 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:59656 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqpn-0006U2-0Y for patch@linaro.org; Mon, 04 Sep 2017 08:50:37 -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> X-Mailer: git-send-email 2.7.4 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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(-) -- 2.7.4 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 template_syn, return syn; } +static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type, + uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi) +{ + CPUARMState *env = &cpu->env; + int target_el; + bool same_el; + uint32_t syn, exc; + + target_el = exception_target_el(env); + if (fi->stage2) { + target_el = 2; + env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4; + } + same_el = (arm_current_el(env) == target_el); + + if (fsc == 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 != 2 && !arm_el_is_aa64(env, target_el)); + } + + if (access_type == MMU_INST_FETCH) { + syn = syn_insn_abort(same_el, 0, fi->s1ptw, fsc); + exc = EXCP_PREFETCH_ABORT; + } else { + syn = merge_syn_data_abort(env->exception.syndrome, target_el, + same_el, fi->s1ptw, + access_type == MMU_DATA_STORE, + fsc); + if (access_type == MMU_DATA_STORE + && arm_feature(env, ARM_FEATURE_V6)) { + fsr |= (1 << 11); + } + exc = EXCP_DATA_ABORT; + } + + env->exception.vaddress = addr; + env->exception.fsr = 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, MMUAccessType access_type, ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi); if (unlikely(ret)) { ARMCPU *cpu = ARM_CPU(cs); - CPUARMState *env = &cpu->env; - uint32_t syn, exc, fsc; - unsigned int target_el; - bool same_el; + uint32_t fsc; if (retaddr) { /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr); } - target_el = exception_target_el(env); - if (fi.stage2) { - target_el = 2; - env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; - } - same_el = arm_current_el(env) == 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, MMUAccessType access_type, fsc = extract32(fsr, 0, 6); } else { /* Short format FSR : this fault will never actually be reported - * to an EL that uses a syndrome register. Check that here, - * and use a (currently) reserved FSR code in case the constructed - * 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 != 2 && !arm_el_is_aa64(env, target_el)); fsc = 0x3f; } - /* For insn and data aborts we assume there is no instruction syndrome - * information; this is always true for exceptions reported to EL1. - */ - if (access_type == MMU_INST_FETCH) { - syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc); - exc = EXCP_PREFETCH_ABORT; - } else { - syn = merge_syn_data_abort(env->exception.syndrome, target_el, - same_el, fi.s1ptw, - access_type == MMU_DATA_STORE, fsc); - if (access_type == MMU_DATA_STORE - && arm_feature(env, ARM_FEATURE_V6)) { - fsr |= (1 << 11); - } - exc = EXCP_DATA_ABORT; - } - - env->exception.vaddress = addr; - env->exception.fsr = fsr; - raise_exception(env, exc, syn, target_el); + deliver_fault(cpu, addr, access_type, fsr, fsc, &fi); } } @@ -191,9 +207,8 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; - int target_el; - bool same_el; - uint32_t syn; + uint32_t fsr, fsc; + ARMMMUFaultInfo fi = {}; ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx); if (retaddr) { @@ -201,28 +216,17 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, cpu_restore_state(cs, retaddr); } - target_el = exception_target_el(env); - same_el = (arm_current_el(env) == target_el); - - env->exception.vaddress = 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 = (1 << 9) | 0x21; + fsr = (1 << 9) | 0x21; } else { - env->exception.fsr = 0x1; - } - - if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) { - env->exception.fsr |= (1 << 11); + fsr = 0x1; } + fsc = 0x21; - syn = merge_syn_data_abort(env->exception.syndrome, target_el, - same_el, 0, access_type == MMU_DATA_STORE, - 0x21); - raise_exception(env, EXCP_DATA_ABORT, syn, target_el); + deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi); } #endif /* !defined(CONFIG_USER_ONLY) */