From patchwork Tue Dec 18 18:04:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 154173 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp4015088ljp; Tue, 18 Dec 2018 10:06:29 -0800 (PST) X-Google-Smtp-Source: AFSGD/UKC2/3LH8xmgcYe/tPi94GWjPtf85L8PWeI8X1wvfppJi7hGwX9xngwX9QyTNggSll3Iyi X-Received: by 2002:a81:ac56:: with SMTP id z22mr19786269ywj.40.1545156389443; Tue, 18 Dec 2018 10:06:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545156389; cv=none; d=google.com; s=arc-20160816; b=tnJqcjp4PKYxPgQPClJRxBGWG9QWkY2au5nZJtn6or2jcFVQxo/ZZgRrsA5XN5nLjE f0Kzs3pMec1uGjlLxLmgM6x/p0hSQ+ob98I4AmGaFt6/pjJJdgurFTy6Voe0kFpO1Dt/ 7ZzlAprsgH/wQ2i6dHKwyZ9JcuUF2MX9qA74n2+H+h1+QvIg0/zefOV3KVrvfDDTZM4d MzuKVxFxsUWxzkNFbMKV4xpNKitMeI/mV4bryYxWvm0rLuwBlN+KvASbHGw+gDvTnqA7 JaQRgY+SvRoTJcariZ8WqGBzqrgDv0Wzn+kxw7c0eXTjAl9Zwb/7hif6I9FMs5hBb//J mRYg== 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:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from; bh=1QaCdM9HmcZGKuPgaRPQTCc2fZakpKUrGXbtyarw0Rs=; b=U0Iaww/2WxfIzDWEm4pRObP0Fl4Op9fT9XZYt6SzNKtBZCzwa7KS31kCTeG+vYLV9x Ob2pZ/heyQ3IOS0qfoqOyJV448PgQHWODapS+mAO/4L/sf8/9vssMFVx0QwHsjrEEclq jlYdPiXWysJdETzEu1wZ9sylqJE9nFoIf4fVdpcfOlDqQz3CqdtCrhLwBb0SXrrAdZ+l gBYqZuFB2qaO1x/7o7zUkK1rRBLJ5jYQdR2I923MMMz466k+LB8/t4PIyo/AeaUNq5GS mBak9wvYsAjOHxEE7zG3O4uMjDPo8cKk4B6LmeqhIzyBRH1jIWPb1qkXw1b52PvRTxfz bOAw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id q128si10394705ybc.142.2018.12.18.10.06.29 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 18 Dec 2018 10:06:29 -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; 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 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1gZJjH-0006aK-Ho; Tue, 18 Dec 2018 18:04:27 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1gZJjG-0006a9-Hb for xen-devel@lists.xenproject.org; Tue, 18 Dec 2018 18:04:26 +0000 X-Inumbo-ID: 5afc5553-02ef-11e9-8e1d-bc764e045a96 Received: from foss.arm.com (unknown [217.140.101.70]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTP id 5afc5553-02ef-11e9-8e1d-bc764e045a96; Tue, 18 Dec 2018 18:04:25 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A7B0715AB; Tue, 18 Dec 2018 10:04:25 -0800 (PST) Received: from e108454-lin.cambridge.arm.com (e108454-lin.cambridge.arm.com [10.1.196.50]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AFD7F3F5C0; Tue, 18 Dec 2018 10:04:24 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Tue, 18 Dec 2018 18:04:14 +0000 Message-Id: <20181218180417.22134-2-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181218180417.22134-1-julien.grall@arm.com> References: <20181218180417.22134-1-julien.grall@arm.com> Subject: [Xen-devel] [PATCH for-4.12 v4 1/4] xen/arm: vcpreg: Add wrappers to handle co-proc access trapped by HCR_EL2.TVM X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Julien Grall , Stefano Stabellini MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" A follow-up patch will require to emulate some accesses to some co-processors registers trapped by HCR_EL2.TVM. When set, all NS EL1 writes to the virtual memory control registers will be trapped to the hypervisor. This patch adds the infrastructure to passthrough the access to host registers. For convenience a bunch of helpers have been added to generate the different helpers. Note that HCR_EL2.TVM will be set in a follow-up patch dynamically. Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini --- Changes in v3: - Add Stefano's reviewed-by Changes in v2: - Add missing include vreg.h - Fixup mask TMV_REG32_COMBINED - Update comments --- xen/arch/arm/vcpreg.c | 149 +++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/cpregs.h | 1 + 2 files changed, 150 insertions(+) diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c index 7b783e4bcc..550c25ec3f 100644 --- a/xen/arch/arm/vcpreg.c +++ b/xen/arch/arm/vcpreg.c @@ -23,8 +23,129 @@ #include #include #include +#include #include +/* + * Macros to help generating helpers for registers trapped when + * HCR_EL2.TVM is set. + * + * Note that it only traps NS write access from EL1. + * + * - TVM_REG() should not be used outside of the macros. It is there to + * help defining TVM_REG32() and TVM_REG64() + * - TVM_REG32(regname, xreg) and TVM_REG64(regname, xreg) are used to + * resp. generate helper accessing 32-bit and 64-bit register. "regname" + * is the Arm32 name and "xreg" the Arm64 name. + * - TVM_REG32_COMBINED(lowreg, hireg, xreg) are used to generate a + * pair of register sharing the same Arm64 register, but are 2 distinct + * Arm32 registers. "lowreg" and "hireg" contains the name for on Arm32 + * registers, "xreg" contains the name for the combined register on Arm64. + * The definition of "lowreg" and "higreg" match the Armv8 specification, + * this means "lowreg" is an alias to xreg[31:0] and "high" is an alias to + * xreg[63:32]. + * + */ + +/* The name is passed from the upper macro to workaround macro expansion. */ +#define TVM_REG(sz, func, reg...) \ +static bool func(struct cpu_user_regs *regs, uint##sz##_t *r, bool read) \ +{ \ + GUEST_BUG_ON(read); \ + WRITE_SYSREG##sz(*r, reg); \ + \ + return true; \ +} + +#define TVM_REG32(regname, xreg) TVM_REG(32, vreg_emulate_##regname, xreg) +#define TVM_REG64(regname, xreg) TVM_REG(64, vreg_emulate_##regname, xreg) + +#ifdef CONFIG_ARM_32 +#define TVM_REG32_COMBINED(lowreg, hireg, xreg) \ + /* Use TVM_REG directly to workaround macro expansion. */ \ + TVM_REG(32, vreg_emulate_##lowreg, lowreg) \ + TVM_REG(32, vreg_emulate_##hireg, hireg) + +#else /* CONFIG_ARM_64 */ +#define TVM_REG32_COMBINED(lowreg, hireg, xreg) \ +static bool vreg_emulate_##xreg(struct cpu_user_regs *regs, uint32_t *r, \ + bool read, bool hi) \ +{ \ + register_t reg = READ_SYSREG(xreg); \ + \ + GUEST_BUG_ON(read); \ + if ( hi ) /* reg[63:32] is AArch32 register hireg */ \ + { \ + reg &= GENMASK(31, 0); \ + reg |= ((uint64_t)*r) << 32; \ + } \ + else /* reg[31:0] is AArch32 register lowreg. */ \ + { \ + reg &= GENMASK(63, 32); \ + reg |= *r; \ + } \ + WRITE_SYSREG(reg, xreg); \ + \ + return true; \ +} \ + \ +static bool vreg_emulate_##lowreg(struct cpu_user_regs *regs, uint32_t *r, \ + bool read) \ +{ \ + return vreg_emulate_##xreg(regs, r, read, false); \ +} \ + \ +static bool vreg_emulate_##hireg(struct cpu_user_regs *regs, uint32_t *r, \ + bool read) \ +{ \ + return vreg_emulate_##xreg(regs, r, read, true); \ +} +#endif + +/* Defining helpers for emulating co-processor registers. */ +TVM_REG32(SCTLR, SCTLR_EL1) +/* + * AArch32 provides two way to access TTBR* depending on the access + * size, whilst AArch64 provides one way. + * + * When using AArch32, for simplicity, use the same access size as the + * guest. + */ +#ifdef CONFIG_ARM_32 +TVM_REG32(TTBR0_32, TTBR0_32) +TVM_REG32(TTBR1_32, TTBR1_32) +#else +TVM_REG32(TTBR0_32, TTBR0_EL1) +TVM_REG32(TTBR1_32, TTBR1_EL1) +#endif +TVM_REG64(TTBR0, TTBR0_EL1) +TVM_REG64(TTBR1, TTBR1_EL1) +/* AArch32 registers TTBCR and TTBCR2 share AArch64 register TCR_EL1. */ +TVM_REG32_COMBINED(TTBCR, TTBCR2, TCR_EL1) +TVM_REG32(DACR, DACR32_EL2) +TVM_REG32(DFSR, ESR_EL1) +TVM_REG32(IFSR, IFSR32_EL2) +/* AArch32 registers DFAR and IFAR shares AArch64 register FAR_EL1. */ +TVM_REG32_COMBINED(DFAR, IFAR, FAR_EL1) +TVM_REG32(ADFSR, AFSR0_EL1) +TVM_REG32(AIFSR, AFSR1_EL1) +/* AArch32 registers MAIR0 and MAIR1 share AArch64 register MAIR_EL1. */ +TVM_REG32_COMBINED(MAIR0, MAIR1, MAIR_EL1) +/* AArch32 registers AMAIR0 and AMAIR1 share AArch64 register AMAIR_EL1. */ +TVM_REG32_COMBINED(AMAIR0, AMAIR1, AMAIR_EL1) +TVM_REG32(CONTEXTIDR, CONTEXTIDR_EL1) + +/* Macro to generate easily case for co-processor emulation. */ +#define GENERATE_CASE(reg, sz) \ + case HSR_CPREG##sz(reg): \ + { \ + bool res; \ + \ + res = vreg_emulate_cp##sz(regs, hsr, vreg_emulate_##reg); \ + ASSERT(res); \ + break; \ + } + void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr) { const struct hsr_cp32 cp32 = hsr.cp32; @@ -65,6 +186,31 @@ void do_cp15_32(struct cpu_user_regs *regs, const union hsr hsr) break; /* + * HCR_EL2.TVM + * + * ARMv8 (DDI 0487D.a): Table D1-38 + */ + GENERATE_CASE(SCTLR, 32) + GENERATE_CASE(TTBR0_32, 32) + GENERATE_CASE(TTBR1_32, 32) + GENERATE_CASE(TTBCR, 32) + GENERATE_CASE(TTBCR2, 32) + GENERATE_CASE(DACR, 32) + GENERATE_CASE(DFSR, 32) + GENERATE_CASE(IFSR, 32) + GENERATE_CASE(DFAR, 32) + GENERATE_CASE(IFAR, 32) + GENERATE_CASE(ADFSR, 32) + GENERATE_CASE(AIFSR, 32) + /* AKA PRRR */ + GENERATE_CASE(MAIR0, 32) + /* AKA NMRR */ + GENERATE_CASE(MAIR1, 32) + GENERATE_CASE(AMAIR0, 32) + GENERATE_CASE(AMAIR1, 32) + GENERATE_CASE(CONTEXTIDR, 32) + + /* * MDCR_EL2.TPM * * ARMv7 (DDI 0406C.b): B1.14.17 @@ -193,6 +339,9 @@ void do_cp15_64(struct cpu_user_regs *regs, const union hsr hsr) return inject_undef_exception(regs, hsr); break; + GENERATE_CASE(TTBR0, 64) + GENERATE_CASE(TTBR1, 64) + /* * CPTR_EL2.T{0..9,12..13} * diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h index 97a3c6f1c1..8fd344146e 100644 --- a/xen/include/asm-arm/cpregs.h +++ b/xen/include/asm-arm/cpregs.h @@ -140,6 +140,7 @@ /* CP15 CR2: Translation Table Base and Control Registers */ #define TTBCR p15,0,c2,c0,2 /* Translation Table Base Control Register */ +#define TTBCR2 p15,0,c2,c0,3 /* Translation Table Base Control Register 2 */ #define TTBR0 p15,0,c2 /* Translation Table Base Reg. 0 */ #define TTBR1 p15,1,c2 /* Translation Table Base Reg. 1 */ #define HTTBR p15,4,c2 /* Hyp. Translation Table Base Register */