From patchwork Tue Dec 12 19:02:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 121632 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp4508250qgn; Tue, 12 Dec 2017 11:04:23 -0800 (PST) X-Google-Smtp-Source: ACJfBosBNUOnGfPIaThlXkCH0CmWDB2arZAmcXgFUCKnmeXvZQdT0okwIXodcILHV5wvl2Fy/7Mv X-Received: by 10.107.182.196 with SMTP id g187mr6168615iof.225.1513105463769; Tue, 12 Dec 2017 11:04:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513105463; cv=none; d=google.com; s=arc-20160816; b=KtDrKpPoM7oKWhBqykV6JT4W9QaxmjHbt+6hbOZOyhMlw6guZvY2GQdTvcrl5WSuhP 1qcaSXkySlSveq3U7sgt91UQvcelVuZS+QDfcQmVRBGIF/BU0210kJybMTCx1JL9yLKP PXL7RVDYwjwuIPdTrdQBtZuhkGYD/b6IJz0CFZzrrNC/YCXR88bHH090ECVhlAArzfHo 7C16l/IyqxxhBGC+qiZZd5p50iQrDwVlyhbIUr8SuWvj8hevPkOKRJY12NBBw56VJacf 4IYtFtVht1rnbatLyPxVvw+gjVuu836hxZc/C5LUbBP9HSFjHrXFDHwokxU1ayShLIHm U/rw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=CWVnWPQp0AwJsq9oV9GFlaRglZWxR6tIUy5FGVDM/fk=; b=TSz3oFLXZN+LaMZC5plV5qfu51FwlrAS9a0IudN09OOSBWucfi1ASm3M5RGRWu3myZ ZndnLTUhY0ZdybWMC01YQtCX31igATeLLeYJSJ1UMytRcqA9AQa7uvuSFyhVpbUxksoK OZQzIyBDD0H3EuxJ7jiwTKTewLI8/LQovVAOR9BI5cQQktebIokAz4RyBylo5yXyaSBJ Wr1LAQVM0hIDb1Bw91Ym6Y+UudfNnXHJknRtSaGhHkj7sP864PZh0PMZgaWGK336clAx 2//u0nGehAnSzmFtR9ypcq1ohxtFWmhLGvvQAqScTMqV/UKnCxIwB9rqVy07UBbYJYsW 4BkA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZLSsQoW+; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id f32si12696809iod.248.2017.12.12.11.04.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Dec 2017 11:04:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=ZLSsQoW+; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOppJ-0002s9-OQ; Tue, 12 Dec 2017 19:02:49 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eOppI-0002qB-Io for xen-devel@lists.xen.org; Tue, 12 Dec 2017 19:02:48 +0000 X-Inumbo-ID: f703e8b6-df6e-11e7-b4a6-bc764e045a96 Received: from mail-wm0-x242.google.com (unknown [2a00:1450:400c:c09::242]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id f703e8b6-df6e-11e7-b4a6-bc764e045a96; Tue, 12 Dec 2017 20:02:14 +0100 (CET) Received: by mail-wm0-x242.google.com with SMTP id 64so699056wme.3 for ; Tue, 12 Dec 2017 11:02:46 -0800 (PST) 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=Zv2pZFvHcS6glpBpgJMzZ5Xb62L+gscMb+BNHVIr3sE=; b=ZLSsQoW+kgNM+0mXRHWUo5T5DLYsVNFCi9QHRDZmQQtRMQdxxSqJ7wKL5AGeX3cI7X sMG+ql6dXzfJB8lYvNshe9fl3DfMBQLC82VjIHGMpqyxZTBjwZWFvgeBQd3/ucbDvLzO 49qsymU9LJnK8/mYPp/A7TtlQX01huq6Z0v7w= 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=Zv2pZFvHcS6glpBpgJMzZ5Xb62L+gscMb+BNHVIr3sE=; b=rQBYVGFRlfsiY6VzXcW4109QSb4klSGssbo5TuLpke77uVYGQod3P41+2HcdqhM6Hr yi2FOQJCo9C7DxAeBTok8f94XwJ9RsIYNJlF0v22Bv97aGOnp9gBvAOYhOOvQOrxRFQR U3dpwlTf0tNQHx9Xn56LX/x0O5RF3VIgHXucOJ1fpcSvTi5tAeEQfH5xaw9Ls+AVYufm I0cl0ir2gqZr8x5diWZ7yfL7zo2zLs/TEycKGQVua2ckGbjxQ5/MpvsaHHbuc00EBtSK 6rr7CvaITfvmeevq+Z8UD49trhD+fp5JkyHV0I2lqvE6ozqXG1NK/h8Q5OaqVYFseYGo dAXw== X-Gm-Message-State: AKGB3mL2tO7pUVEz+MZ5oAgWcfBTi6AbzCMHzkn//JuMl0f9o5sY75Ev Z54nB0ldJVaTIEP3I33VBmcALLO6uYA= X-Received: by 10.28.109.139 with SMTP id b11mr2501207wmi.85.1513105365077; Tue, 12 Dec 2017 11:02:45 -0800 (PST) Received: from e108454-lin.cambridge.arm.com ([2001:41d0:1:6c23::1]) by smtp.gmail.com with ESMTPSA id n14sm207508wmh.37.2017.12.12.11.02.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Dec 2017 11:02:44 -0800 (PST) From: Julien Grall To: xen-devel@lists.xen.org Date: Tue, 12 Dec 2017 19:02:12 +0000 Message-Id: <20171212190212.5535-17-julien.grall@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171212190212.5535-1-julien.grall@linaro.org> References: <20171212190212.5535-1-julien.grall@linaro.org> Cc: sstabellini@kernel.org, Julien Grall , andre.przywara@linaro.org Subject: [Xen-devel] [v2 16/16] xen/arm: traps: Merge do_trap_instr_abort_guest and do_trap_data_abort_guest X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The two helpers do_trap_instr_abort_guest and do_trap_data_abort_guest are used trap stage-2 abort. While the former is only handling prefetch abort and the latter data abort, they are very similarly and does not warrant to have separate helpers. For instance, merging the both will make easier to maintain stage-2 abort handling. So consolidate the two helpers in a new helper do_trap_stage2_abort. Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini --- Changes in v2 - Fix the way to compute npfec.write_access --- xen/arch/arm/traps.c | 133 ++++++++++++++++----------------------------------- 1 file changed, 41 insertions(+), 92 deletions(-) diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 082396c26d..013c1600ec 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1861,79 +1861,6 @@ static inline bool hpfar_is_valid(bool s1ptw, uint8_t fsc) return s1ptw || (fsc == FSC_FLT_TRANS && !check_workaround_834220()); } -static void do_trap_instr_abort_guest(struct cpu_user_regs *regs, - const union hsr hsr) -{ - int rc; - register_t gva; - uint8_t fsc = hsr.iabt.ifsc & ~FSC_LL_MASK; - paddr_t gpa; - mfn_t mfn; - - gva = get_hfar(false /* is_data */); - - /* - * If this bit has been set, it means that this instruction abort is caused - * by a guest external abort. We can handle this instruction abort as guest - * SError. - */ - if ( hsr.iabt.eat ) - return __do_trap_serror(regs, true); - - - if ( hpfar_is_valid(hsr.iabt.s1ptw, fsc) ) - gpa = get_faulting_ipa(gva); - else - { - /* - * Flush the TLB to make sure the DTLB is clear before - * doing GVA->IPA translation. If we got here because of - * an entry only present in the ITLB, this translation may - * still be inaccurate. - */ - flush_tlb_local(); - - /* - * We may not be able to translate because someone is - * playing with the Stage-2 page table of the domain. - * Return to the guest. - */ - rc = gva_to_ipa(gva, &gpa, GV2M_READ); - if ( rc == -EFAULT ) - return; /* Try again */ - } - - switch ( fsc ) - { - case FSC_FLT_PERM: - { - const struct npfec npfec = { - .insn_fetch = 1, - .gla_valid = 1, - .kind = hsr.iabt.s1ptw ? npfec_kind_in_gpt : npfec_kind_with_gla - }; - - p2m_mem_access_check(gpa, gva, npfec); - /* - * The only way to get here right now is because of mem_access, - * thus reinjecting the exception to the guest is never required. - */ - return; - } - case FSC_FLT_TRANS: - /* - * The PT walk may have failed because someone was playing - * with the Stage-2 page table. Walk the Stage-2 PT to check - * if the entry exists. If it's the case, return to the guest - */ - mfn = gfn_to_mfn(current->domain, _gfn(paddr_to_pfn(gpa))); - if ( !mfn_eq(mfn, INVALID_MFN) ) - return; - } - - inject_iabt_exception(regs, gva, hsr.len); -} - static bool try_handle_mmio(struct cpu_user_regs *regs, const union hsr hsr, paddr_t gpa) @@ -1945,6 +1872,8 @@ static bool try_handle_mmio(struct cpu_user_regs *regs, }; int rc; + ASSERT(hsr.ec == HSR_EC_DATA_ABORT_LOWER_EL); + /* stage-1 page table should never live in an emulated MMIO region */ if ( dabt.s1ptw ) return false; @@ -2000,29 +1929,43 @@ static bool try_map_mmio(gfn_t gfn) return !map_regions_p2mt(d, gfn, 1, mfn, p2m_mmio_direct_c); } -static void do_trap_data_abort_guest(struct cpu_user_regs *regs, - const union hsr hsr) +static void do_trap_stage2_abort_guest(struct cpu_user_regs *regs, + const union hsr hsr) { - const struct hsr_dabt dabt = hsr.dabt; + /* + * The encoding of hsr_iabt is a subset of hsr_dabt. So use + * hsr_dabt to represent an abort fault. + */ + const struct hsr_xabt xabt = hsr.xabt; int rc; vaddr_t gva; paddr_t gpa; - uint8_t fsc = hsr.dabt.dfsc & ~FSC_LL_MASK; + uint8_t fsc = xabt.fsc & ~FSC_LL_MASK; mfn_t mfn; + bool is_data = (hsr.ec == HSR_EC_DATA_ABORT_LOWER_EL); /* - * If this bit has been set, it means that this data abort is caused - * by a guest external abort. We treat this data abort as guest SError. + * If this bit has been set, it means that this stage-2 abort is caused + * by a guest external abort. We treat this stage-2 abort as guest SError. */ - if ( dabt.eat ) + if ( xabt.eat ) return __do_trap_serror(regs, true); - gva = get_hfar(true /* is_data */); + gva = get_hfar(is_data); - if ( hpfar_is_valid(dabt.s1ptw, fsc) ) + if ( hpfar_is_valid(xabt.s1ptw, fsc) ) gpa = get_faulting_ipa(gva); else { + /* + * Flush the TLB to make sure the DTLB is clear before + * doing GVA->IPA translation. If we got here because of + * an entry only present in the ITLB, this translation may + * still be inaccurate. + */ + if ( !is_data ) + flush_tlb_local(); + rc = gva_to_ipa(gva, &gpa, GV2M_READ); /* * We may not be able to translate because someone is @@ -2038,10 +1981,11 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, case FSC_FLT_PERM: { const struct npfec npfec = { - .read_access = !dabt.write, - .write_access = dabt.write, + .insn_fetch = !is_data, + .read_access = is_data && !hsr.dabt.write, + .write_access = is_data && hsr.dabt.write, .gla_valid = 1, - .kind = dabt.s1ptw ? npfec_kind_in_gpt : npfec_kind_with_gla + .kind = xabt.s1ptw ? npfec_kind_in_gpt : npfec_kind_with_gla }; p2m_mem_access_check(gpa, gva, npfec); @@ -2055,8 +1999,10 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, /* * Attempt first to emulate the MMIO as the data abort will * likely happen in an emulated region. + * + * Note that emulated region cannot be executed */ - if ( try_handle_mmio(regs, hsr, gpa) ) + if ( is_data && try_handle_mmio(regs, hsr, gpa) ) { advance_pc(regs, hsr); return; @@ -2071,18 +2017,21 @@ static void do_trap_data_abort_guest(struct cpu_user_regs *regs, if ( !mfn_eq(mfn, INVALID_MFN) ) return; - if ( try_map_mmio(gaddr_to_gfn(gpa)) ) + if ( is_data && try_map_mmio(gaddr_to_gfn(gpa)) ) return; break; default: - gprintk(XENLOG_WARNING, "Unsupported DFSC: HSR=%#x DFSC=%#x\n", - hsr.bits, dabt.dfsc); + gprintk(XENLOG_WARNING, "Unsupported FSC: HSR=%#x DFSC=%#x\n", + hsr.bits, xabt.fsc); } gdprintk(XENLOG_DEBUG, "HSR=0x%x pc=%#"PRIregister" gva=%#"PRIvaddr " gpa=%#"PRIpaddr"\n", hsr.bits, regs->pc, gva, gpa); - inject_dabt_exception(regs, gva, hsr.len); + if ( is_data ) + inject_dabt_exception(regs, gva, hsr.len); + else + inject_iabt_exception(regs, gva, hsr.len); } static void enter_hypervisor_head(struct cpu_user_regs *regs) @@ -2215,11 +2164,11 @@ void do_trap_guest_sync(struct cpu_user_regs *regs) case HSR_EC_INSTR_ABORT_LOWER_EL: perfc_incr(trap_iabt); - do_trap_instr_abort_guest(regs, hsr); + do_trap_stage2_abort_guest(regs, hsr); break; case HSR_EC_DATA_ABORT_LOWER_EL: perfc_incr(trap_dabt); - do_trap_data_abort_guest(regs, hsr); + do_trap_stage2_abort_guest(regs, hsr); break; default: