From nobody Mon Feb 9 10:39:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1551978490120253.78785297481318; Thu, 7 Mar 2019 09:08:10 -0800 (PST) Received: from localhost ([127.0.0.1]:55588 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h1wV3-0008Gv-KI for importer@patchew.org; Thu, 07 Mar 2019 12:08:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58769) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h1wRx-0006EB-0z for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:04:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h1wRp-0004Kl-MI for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:04:51 -0500 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]:44350) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h1wRp-0004Iu-40 for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:04:45 -0500 Received: by mail-pg1-x542.google.com with SMTP id j3so11726498pgm.11 for ; Thu, 07 Mar 2019 09:04:43 -0800 (PST) Received: from cloudburst.twiddle.net (97-113-188-82.tukw.qwest.net. [97.113.188.82]) by smtp.gmail.com with ESMTPSA id r82sm10040562pfa.161.2019.03.07.09.04.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 07 Mar 2019 09:04:41 -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; bh=VsPmuBQhZLLX1wswLM9b+8N9PDFbNWoFiy5AAWe5Ewg=; b=ZHul7h2mU/nVv63zavdnir6guwfjshXxNrWMbSn2hkHPTkxZ7l6XrpFO85GWBd+9sT QJvhdu6O6FsQRNIUcQk4fKi/y2j9CkotObcIaiehUbO4Os3rDHUYM+IMWMD2ZEoqof4f kp9YZZPRv5sJb+grLkbCWwHCYb8kXKLnWORrxuthuH3Fv+KQAipzg34cou/7wU6p4/WE J+4wUbjcPvbdleBY6GpdwD9T7Npac6NBY2OqCUfcGJc0oTmwGH2V3EJkCWzhbJcvdDPq Bw8OmouA1cHuR1A8r7TXkm5+NokARK55PgLfpOZrrJiPJ4i/NeNQ/qWCkWXb8Y8b+liS lsSQ== 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; bh=VsPmuBQhZLLX1wswLM9b+8N9PDFbNWoFiy5AAWe5Ewg=; b=aS5OhVwlom8LUBT+y142qNVGZ17z/5iR8hzmyAE1Rh4+t93drqZB5h4KdV5ANWYfL8 ods8JAZRk8jyFBuRLK8uGPmJgLVVBIHgc4vkbRpqDVyf/7/oy73lkvUa2ifnDkHvfKz/ R34vcZW3D5bnnyLM0CLCLo1hY5+JyR9mMFlBoqOUhe/f4U+7bflCjAklqiFiu/LYcFT6 QU1V6QRZR7UyXt2w8oHwSwHP+ilLTvoC9dBbW5tm5UlHRgVx4LM0RiyYiysoFCfbrfjo oSS0I7g+2+XhEyaZqvs9lZy/SPO0uviTPhb+UD1z1oH97u3qVSbyYhlR/yNhGQRuH65Q sw0g== X-Gm-Message-State: APjAAAVtZnaZkmMTRJSV1kn5NIsbVv5hhNkJHsHfXEOGOVhOOvSfos7Z Vp3A2N5WhdY6Av/ELOORHnM85NWOca0= X-Google-Smtp-Source: APXvYqyHKJez37zerNu1w2V58HeZFV5Wwk8trXkzV8xWSxoHOtRV6x9EgV5xEEN8V2PJQoO9HykAfg== X-Received: by 2002:a17:902:2bc9:: with SMTP id l67mr13969086plb.241.1551978282142; Thu, 07 Mar 2019 09:04:42 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 7 Mar 2019 09:04:18 -0800 Message-Id: <20190307170440.3113-1-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::542 Subject: [Qemu-devel] [PATCH v4 00/22] target/arm: Implement ARMv8.5-MemTag, system mode 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: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Major changes since v3: * User mode support dropped. There's nothing baked about the userland abi yet. * Introduce a new softmmu TLB to avoid duplicating the address space -> flatview -> memory region -> ram offset craziness that the TLB already manages. * Tested with a truly hack-full kernel patch and test case below. Real kernel support for MTE will require support for paging. I ignore that and pin some pages, which is good enough for the test case to run. r~ Richard Henderson (22): target/arm: Add MTE_ACTIVE to tb_flags target/arm: Extract TCMA with ARMVAParameters target/arm: Add MTE system registers target/arm: Add helper_mte_check{1,2} target/arm: Suppress tag check for sp+offset target/arm: Implement the IRG instruction target/arm: Implement ADDG, SUBG instructions target/arm: Implement the GMI instruction target/arm: Implement the SUBP instruction target/arm: Define arm_cpu_do_unaligned_access for CONFIG_USER_ONLY target/arm: Implement LDG, STG, ST2G instructions target/arm: Implement the STGP instruction target/arm: Implement the LDGM and STGM instructions target/arm: Implement the access tag cache flushes target/arm: Clean address for DC ZVA target/arm: Implement data cache set allocation tags target/arm: Set PSTATE.TCO on exception entry target/arm: Cache the Tagged bit for a page in MemTxAttrs target/arm: Create tagged ram when MTE is enabled target/arm: Create a TLB entry for tag physical address space target/arm: Add allocation tag storage for system mode target/arm: Enable MTE target/arm/cpu.h | 68 ++++- target/arm/helper-a64.h | 16 ++ target/arm/internals.h | 29 ++ target/arm/translate.h | 2 + hw/arm/virt.c | 33 +++ target/arm/cpu.c | 21 +- target/arm/cpu64.c | 1 + target/arm/helper.c | 241 ++++++++++++++-- target/arm/mte_helper.c | 559 +++++++++++++++++++++++++++++++++++++ target/arm/op_helper.c | 33 ++- target/arm/translate-a64.c | 338 +++++++++++++++++++--- target/arm/Makefile.objs | 2 +- 12 files changed, 1244 insertions(+), 99 deletions(-) create mode 100644 target/arm/mte_helper.c --- kernel patch diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpuc= aps.h index 82e9099834ae..b7aa17d9a044 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -60,7 +60,8 @@ #define ARM64_HAS_ADDRESS_AUTH_IMP_DEF 39 #define ARM64_HAS_GENERIC_AUTH_ARCH 40 #define ARM64_HAS_GENERIC_AUTH_IMP_DEF 41 +#define ARM64_HAS_MTE 42 =20 -#define ARM64_NCAPS 42 +#define ARM64_NCAPS 43 =20 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysre= g.h index 72dc4c011014..996ab091ae99 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -451,6 +451,7 @@ =20 /* Common SCTLR_ELx flags. */ #define SCTLR_ELx_DSSBS (_BITUL(44)) +#define SCTLR_ELx_ATA (_BITUL(43)) #define SCTLR_ELx_ENIA (_BITUL(31)) #define SCTLR_ELx_ENIB (_BITUL(30)) #define SCTLR_ELx_ENDA (_BITUL(27)) @@ -496,6 +497,7 @@ #endif =20 /* SCTLR_EL1 specific flags. */ +#define SCTLR_EL1_ATA0 (_BITUL(42)) #define SCTLR_EL1_UCI (_BITUL(26)) #define SCTLR_EL1_E0E (_BITUL(24)) #define SCTLR_EL1_SPAN (_BITUL(23)) @@ -596,6 +598,7 @@ =20 /* id_aa64pfr1 */ #define ID_AA64PFR1_SSBS_SHIFT 4 +#define ID_AA64PFR1_MTE_SHIFT 8 =20 #define ID_AA64PFR1_SSBS_PSTATE_NI 0 #define ID_AA64PFR1_SSBS_PSTATE_ONLY 1 diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index f6d84e2c92fe..f54c1e7f40aa 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -178,6 +178,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = =3D { =20 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] =3D { ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1= _SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1= _MTE_SHIFT, 4, 0), ARM64_FTR_END, }; =20 @@ -1203,6 +1204,11 @@ static void cpu_enable_address_auth(struct arm64_cpu= _capabilities const *cap) } #endif /* CONFIG_ARM64_PTR_AUTH */ =20 +static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) +{ + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0); +} + static const struct arm64_cpu_capabilities arm64_features[] =3D { { .desc =3D "GIC system register CPU interface", @@ -1480,6 +1486,17 @@ static const struct arm64_cpu_capabilities arm64_fea= tures[] =3D { .matches =3D has_cpuid_feature, }, #endif /* CONFIG_ARM64_PTR_AUTH */ + { + .desc =3D "Memory Tagging", + .capability =3D ARM64_HAS_MTE, + .type =3D ARM64_CPUCAP_SYSTEM_FEATURE, + .matches =3D has_cpuid_feature, + .sys_reg =3D SYS_ID_AA64PFR1_EL1, + .field_pos =3D ID_AA64PFR1_MTE_SHIFT, + .sign =3D FTR_UNSIGNED, + .min_field_value =3D 1, + .cpu_enable =3D cpu_enable_mte, { .desc =3D "GIC system register CPU interface", @@ -1480,6 +1486,17 @@ static const struct arm64_cpu_capabilities arm64_fea= tures[] =3D { .matches =3D has_cpuid_feature, }, #endif /* CONFIG_ARM64_PTR_AUTH */ + { + .desc =3D "Memory Tagging", + .capability =3D ARM64_HAS_MTE, + .type =3D ARM64_CPUCAP_SYSTEM_FEATURE, + .matches =3D has_cpuid_feature, + .sys_reg =3D SYS_ID_AA64PFR1_EL1, + .field_pos =3D ID_AA64PFR1_MTE_SHIFT, + .sign =3D FTR_UNSIGNED, + .min_field_value =3D 1, + .cpu_enable =3D cpu_enable_mte, + }, {}, }; =20 diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 73886a5f1f30..20ebf4a222e8 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -435,14 +435,14 @@ ENTRY(__cpu_setup) * DEVICE_nGnRE 001 00000100 * DEVICE_GRE 010 00001100 * NORMAL_NC 011 01000100 - * NORMAL 100 11111111 + * NORMAL 100 11110000 (Tag) * NORMAL_WT 101 10111011 */ ldr x5, =3DMAIR(0x00, MT_DEVICE_nGnRnE) | \ MAIR(0x04, MT_DEVICE_nGnRE) | \ MAIR(0x0c, MT_DEVICE_GRE) | \ MAIR(0x44, MT_NORMAL_NC) | \ - MAIR(0xff, MT_NORMAL) | \ + MAIR(0xf0, MT_NORMAL) | \ MAIR(0xbb, MT_NORMAL_WT) msr mair_el1, x5 /* --- test case /* * Memory tagging, basic pass cases. */ #include #include #include asm(".arch armv8.5-a+memtag"); int data[16 / sizeof(int)] __attribute__((aligned(16))); int main(int ac, char **av) { int *p0 =3D data; int *p1, *p2; long c; if (mlock(data, sizeof(data)) < 0) { perror("mlock"); return 1; } asm("irg %0,%1,%2" : "=3Dr"(p1) : "r"(p0), "r"(1)); assert(p1 !=3D p0); asm("subp %0,%1,%2" : "=3Dr"(c) : "r"(p0), "r"(p1)); assert(c =3D=3D 0); asm("stg %0, [%0]" : : "r"(p1)); asm("ldg %0, [%1]" : "=3Dr"(p2) : "r"(p0), "0"(p0)); assert(p1 =3D=3D p2); return 0; }