Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp4524664pxb; Tue, 25 Jan 2022 12:14:52 -0800 (PST) X-Google-Smtp-Source: ABdhPJyr6n59WOjXOd04+6AY4xqV+J0pBMA10N87x19+udriXIMxnHFZk7s12aUamRLGshYXGuLz X-Received: by 2002:a17:902:ba81:b0:14b:75c1:573f with SMTP id k1-20020a170902ba8100b0014b75c1573fmr4211206pls.128.1643141692675; Tue, 25 Jan 2022 12:14:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643141692; cv=none; d=google.com; s=arc-20160816; b=Gn0Sn61Mz/+Fvfmnr33EaRKstmYUFkNO0WyiUuRfwYg5Wy+Fr4btzBRUHhj6XL5hZ5 5CSHWQrDNtPL/Dm2nk6xBo+wpmbxCrRD7d2WTyxlFi68JBXECv1/nejRUHbCYhLjjUmw oeMV6AG82rWXKh1CSlpMWuY1gPoPAd7cbGS5L4LetufV3MFVBU++k+vVRYq/gRRc0evm x55CSyUCA0mjxSI46/JeVlbwIc9FdQ2DvCjuJPCpkqGBeLDIjVcdn1PE8PceFyo0v/Z5 hZdy+r4LODPmsSG16myIOGD26h24g+6i/cx1q9cFk98bJfi1SWVMRaNfhjimJ30JsJ/p YOnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from; bh=ahZz2p81pAcOOK5qGSjBxg+fZ+JZP53gYkQ0jcL7lNk=; b=ycqSSjzhAURLLjIsn2mTlrIA4oXZ+QIDdwMAiY+A1QDmglHRFqO22M43kyVe7fAT86 7klk8g3yW9rmHjAO9ngU9htwonzOxEfpqoolzsFRtPLa1BIiWuVDCYNuJm0zz0qOUQQ/ +GZtFasTJEktQfVEvQ9wzGwSQWJkNK/lmFKDPl1RTx4IwfTK4F1Hf+iE0HVBvDqGvktH rgHUDeHWXvzFSHrs7NWDUws6tPOPtzPNO6ZrV5xBeb1M6cqR0787VhC4+sOMyCohtyF6 dC5Q7MoUb6zwzy2P9UetglU71qri3yZEwWI4PiNzPEr1obkPpp/YaW7mjatr2CVLGv2u 3sYA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id v19si20659089pfu.36.2022.01.25.12.14.40; Tue, 25 Jan 2022 12:14:52 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233114AbiAYO3x (ORCPT + 99 others); Tue, 25 Jan 2022 09:29:53 -0500 Received: from foss.arm.com ([217.140.110.172]:46650 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1579101AbiAYOXH (ORCPT ); Tue, 25 Jan 2022 09:23:07 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 12C1013A1; Tue, 25 Jan 2022 06:21:25 -0800 (PST) Received: from p8cg001049571a15.arm.com (unknown [10.163.42.158]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 0B9723F793; Tue, 25 Jan 2022 06:21:20 -0800 (PST) From: Anshuman Khandual To: linux-arm-kernel@lists.infradead.org Cc: Anshuman Khandual , Catalin Marinas , Will Deacon , Mathieu Poirier , Suzuki Poulose , coresight@lists.linaro.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V3 RESEND 6/7] coresight: trbe: Work around the invalid prohibited states Date: Tue, 25 Jan 2022 19:50:36 +0530 Message-Id: <1643120437-14352-7-git-send-email-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com> References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org TRBE implementations affected by Arm erratum #2038923 might get TRBE into an inconsistent view on whether trace is prohibited within the CPU. As a result, the trace buffer or trace buffer state might be corrupted. This happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E, followed by just a single context synchronization event before execution changes from a context, in which trace is prohibited to one where it isn't, or vice versa. In these mentioned conditions, the view of whether trace is prohibited is inconsistent between parts of the CPU, and the trace buffer or the trace buffer state might be corrupted. Work around this problem in the TRBE driver by preventing an inconsistent view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or two ISB instructions if no ERET is to take place. This just updates the TRBE driver as required. Cc: Catalin Marinas Cc: Will Deacon Cc: Mathieu Poirier Cc: Suzuki Poulose Cc: coresight@lists.linaro.org Cc: linux-doc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- arch/arm64/Kconfig | 2 +- drivers/hwtracing/coresight/coresight-trbe.c | 48 +++++++++++++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 823f7cb128dc..f37c9d2d697d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -798,7 +798,7 @@ config ARM64_ERRATUM_2064142 config ARM64_ERRATUM_2038923 bool "Cortex-A510: 2038923: workaround TRBE corruption with enable" - depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in + depends on CORESIGHT_TRBE default y help This option adds the workaround for ARM Cortex-A510 erratum 2038923. diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 4ef944971d8e..6254ba598df2 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -92,11 +92,13 @@ struct trbe_buf { #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE 0 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE 1 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE 2 +#define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE 3 static int trbe_errata_cpucaps[] = { [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE, [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE, [TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142, + [TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923, -1, /* Sentinel, must be the last entry */ }; @@ -179,6 +181,17 @@ static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata) return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE); } +static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudata) +{ + /* + * Errata affected TRBE implementation will need an additional + * context synchronization in order to prevent an inconsistent + * TRBE prohibited region view on the CPU which could possibly + * corrupt the TRBE buffer or the TRBE state. + */ + return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE); +} + static int trbe_alloc_node(struct perf_event *event) { if (event->cpu == -1) @@ -192,6 +205,22 @@ static inline void trbe_drain_buffer(void) dsb(nsh); } +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr) +{ + /* + * Enable the TRBE without clearing LIMITPTR which + * might be required for fetching the buffer limits. + */ + trblimitr |= TRBLIMITR_ENABLE; + write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1); + + /* Synchronize the TRBE enable event */ + isb(); + + if (trbe_needs_ctxt_sync_after_enable(cpudata)) + isb(); +} + static inline void set_trbe_disabled(struct trbe_cpudata *cpudata) { u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1); @@ -555,9 +584,10 @@ static void clr_trbe_status(void) write_sysreg_s(trbsr, SYS_TRBSR_EL1); } -static void set_trbe_limit_pointer_enabled(unsigned long addr) +static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf) { u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1); + unsigned long addr = buf->trbe_limit; WARN_ON(!IS_ALIGNED(addr, (1UL << TRBLIMITR_LIMIT_SHIFT))); WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE)); @@ -585,12 +615,7 @@ static void set_trbe_limit_pointer_enabled(unsigned long addr) trblimitr |= (TRBE_TRIG_MODE_IGNORE & TRBLIMITR_TRIG_MODE_MASK) << TRBLIMITR_TRIG_MODE_SHIFT; trblimitr |= (addr & PAGE_MASK); - - trblimitr |= TRBLIMITR_ENABLE; - write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1); - - /* Synchronize the TRBE enable event */ - isb(); + set_trbe_enabled(buf->cpudata, trblimitr); } static void trbe_enable_hw(struct trbe_buf *buf) @@ -608,7 +633,7 @@ static void trbe_enable_hw(struct trbe_buf *buf) * till now before enabling the TRBE. */ isb(); - set_trbe_limit_pointer_enabled(buf->trbe_limit); + set_trbe_limit_pointer_enabled(buf); } static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *handle, @@ -1013,16 +1038,15 @@ static int arm_trbe_disable(struct coresight_device *csdev) static void trbe_handle_spurious(struct perf_output_handle *handle) { - u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1); + struct trbe_buf *buf = etm_perf_sink_config(handle); + u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1); /* * If the IRQ was spurious, simply re-enable the TRBE * back without modifying the buffer parameters to * retain the trace collected so far. */ - limitr |= TRBLIMITR_ENABLE; - write_sysreg_s(limitr, SYS_TRBLIMITR_EL1); - isb(); + set_trbe_enabled(buf->cpudata, trblimitr); } static int trbe_handle_overflow(struct perf_output_handle *handle) -- 2.25.1