From patchwork Fri Dec 14 11:58:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 153829 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp1972928ljp; Fri, 14 Dec 2018 04:01:16 -0800 (PST) X-Google-Smtp-Source: AFSGD/XlxfeUahBaf0XkjHiw5TFcRhohcYDROLeX5zTdYXRZVMvCg51YilV3qiIOq8jrfDKL8Za5 X-Received: by 2002:a81:33c4:: with SMTP id z187mr2684202ywz.294.1544788876334; Fri, 14 Dec 2018 04:01:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544788876; cv=none; d=google.com; s=arc-20160816; b=fP5RDBZ8qXwe4TxuYJXVvd2G9tNAxGU750wpKOiClopaaJm2OH3gbkHy1QvcieMuPX G5cHs2QyzsxR/4zPpmwuzHWa2jNXzOa3/FVwEUQkN+fhPqh3urioYe9k9Ulj1E1lBCGy vqUkR6ShyzDQ41c8HDpvuCxx3co1MfsBFfSArBlryTTIaulfMfbTM1EqTqOnay/HzyQu CkTzXGn5pEc6OxWzpzFqc60Xcc4BREghDS9oWMXKogwqwT6/HYEVhdd0PHRFYHDHcPMb SdcGZIeAdxszuJYULAMKa9ePY3OTEe9PtbDkNFTKbuz+Hx6wNxsjZRFZaX+xIfJw6EHP +3Tg== 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=VCPMebNytyZ4LYw1xUwWoPJRf7lzfwOJk4HF1b/ObiBCnbHKOXmj/GtQcr5VPq5OGt ngBGouWq9ZZm9Qwf7K+rL70juEInHupfxyQemsS54oGFzV5g1054IaH0dsF09HHg+PxA ghTP+/ik9Htams1JY0eV1KW5IXQ8h9/G7pZpoKlGGLetng9jGEQCuLQBQ8npv0DlbOFu zxP2gagiUwBdQIvUSaS26EXakvRYl6ju9bbTVO0tb6qoPrBMQLscLLFX02uOuZxbB4pB Ohg9zhfTzQhZCIm9ACl1LWRTfNGKxkzfLx+eGNzWRcaCidJn5fUs6xQKzZpgYm51zLOM nw7w== 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 t7si2729981ywt.158.2018.12.14.04.01.16 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 14 Dec 2018 04:01:16 -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 1gXm7W-0001Hn-HD; Fri, 14 Dec 2018 11:59:06 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1gXm7U-0001Gy-Pf for xen-devel@lists.xenproject.org; Fri, 14 Dec 2018 11:59:04 +0000 X-Inumbo-ID: a66a9e38-ff97-11e8-bd65-33d11be83611 Received: from foss.arm.com (unknown [217.140.101.70]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTP id a66a9e38-ff97-11e8-bd65-33d11be83611; Fri, 14 Dec 2018 11:59:03 +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 C633715AD; Fri, 14 Dec 2018 03:59:02 -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 D0D603F575; Fri, 14 Dec 2018 03:59:01 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Fri, 14 Dec 2018 11:58:51 +0000 Message-Id: <20181214115855.6713-2-julien.grall@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181214115855.6713-1-julien.grall@arm.com> References: <20181214115855.6713-1-julien.grall@arm.com> Subject: [Xen-devel] [PATCH for-4.12 v3 1/5] 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 , sstabellini@kernel.org 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 */