Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp5396143rwd; Mon, 12 Jun 2023 04:41:38 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6N1x2hFr5KCb9KfSHaBW3SOKfVZsPHIxmMjZHLN5y8Q8OwvcnoyN40wx3GVKYBK2vr18HA X-Received: by 2002:a05:6402:456:b0:514:9df0:e3ec with SMTP id p22-20020a056402045600b005149df0e3ecmr5140031edw.0.1686570098501; Mon, 12 Jun 2023 04:41:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686570098; cv=none; d=google.com; s=arc-20160816; b=ntQBJxyEDfxhGT9CuL8A55H6Ex+OrrfHXCBKv8WzJCRT/eLRSKJaIC8BuD96eaxuiA 3W/kDxPoX/61DEGOuZuJMVzIqFYTeDyB4iezZDmFtJQRMd78Gam6NugvSPL0SV4xjrTH Wu8XLgHeA2MOqZUvLLrGFMlNKORFJKJ8zcZYKuNqLu9yK9OCRRYd5YzjXBBpZ8Zp4VqK 7oUL26v/Jkr5B6J0TA+/pZ1WVnxSy+24bT5+1lIdEDvld+EhwFogcvq2P8P/j95yUOUK R5cSRuuUnujDaUuz/chLFaOSe0YpXzUHQTsfFIxztHM5/2TShm3Qp//TjrQIngWm5ygk Rl5Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=2BHrqoEAD6p0RLrUHAxXoJvT8cCzGczOACXxcNTX+PQ=; b=RXmZYAk8wPMllKhTSENk7bLGPFXF0cr03eDnrY3NRkYKzLTTE+vDa7kzDxxpojv4Mp 7gw1ni4MprMKn3Crt304QJHZg61AqqjFAvExEdgMi7+PTzQLv3OqWOdENWCMqWjLuffi eBczYF4c8RIaj49lvXo3BWo6PrQlQuO5YvAWHfC/Y0BLznTyzC9MtL7czE0SRsQ+AH+h caeB6x+sEWz47XGTAnvSsjB9VTgKa3PDtNvRTVNc5wf+HA+L50yKsDuaWk8R2hYDgp4F NYC1onJcxovcILiyGa2DjDl/NIpBdbWNql2ayUWZgkkGZTqiXxT6OJ43TiXm8pZGRkFG 5I4g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id l10-20020a056402344a00b005185f8d8bd2si165306edc.337.2023.06.12.04.41.13; Mon, 12 Jun 2023 04:41:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 S237333AbjFLLgr (ORCPT + 99 others); Mon, 12 Jun 2023 07:36:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236365AbjFLLgR (ORCPT ); Mon, 12 Jun 2023 07:36:17 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0EBEE131; Mon, 12 Jun 2023 04:14:32 -0700 (PDT) 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 DE6E42F4; Mon, 12 Jun 2023 04:15:16 -0700 (PDT) Received: from e127643.broadband (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 3F9B03F587; Mon, 12 Jun 2023 04:14:28 -0700 (PDT) From: James Clark To: coresight@lists.linaro.org Cc: James Clark , Suzuki K Poulose , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , John Garry , Will Deacon , linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/5] perf cs-etm: Add exception level consistency check Date: Mon, 12 Jun 2023 12:14:02 +0100 Message-Id: <20230612111403.100613-6-james.clark@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230612111403.100613-1-james.clark@arm.com> References: <20230612111403.100613-1-james.clark@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Assert that our own tracking of the exception level matches what OpenCSD provides. OpenCSD doesn't distinguish between EL0 and EL1 in the memory access callback so the extra tracking was required. But a rough assert can still be done. Signed-off-by: James Clark --- .../perf/util/cs-etm-decoder/cs-etm-decoder.c | 6 +-- .../perf/util/cs-etm-decoder/cs-etm-decoder.h | 4 +- tools/perf/util/cs-etm.c | 41 ++++++++++++++----- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 44c49acd6bff..e917985bbbe6 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -52,15 +52,15 @@ struct cs_etm_decoder { static u32 cs_etm_decoder__mem_access(const void *context, const ocsd_vaddr_t address, - const ocsd_mem_space_acc_t mem_space __maybe_unused, + const ocsd_mem_space_acc_t mem_space, const u8 trace_chan_id, const u32 req_size, u8 *buffer) { struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context; - return decoder->mem_access(decoder->data, trace_chan_id, - address, req_size, buffer); + return decoder->mem_access(decoder->data, trace_chan_id, address, + req_size, buffer, mem_space); } int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder, diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h index 21d403f55d96..272c2efe78ee 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.h @@ -11,6 +11,7 @@ #define INCLUDE__CS_ETM_DECODER_H__ #include +#include #include struct cs_etm_decoder; @@ -19,7 +20,8 @@ struct cs_etm_packet_queue; struct cs_etm_queue; -typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u8, u64, size_t, u8 *); +typedef u32 (*cs_etm_mem_cb_type)(struct cs_etm_queue *, u8, u64, size_t, u8 *, + const ocsd_mem_space_acc_t); struct cs_etmv3_trace_params { u32 reg_ctrl; diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index bd724f3b7e35..22acc4e1f7ce 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -951,7 +951,8 @@ static u8 cs_etm__cpu_mode(struct cs_etm_queue *etmq, u64 address, } static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, - u64 address, size_t size, u8 *buffer) + u64 address, size_t size, u8 *buffer, + const ocsd_mem_space_acc_t mem_space) { u8 cpumode; u64 offset; @@ -967,6 +968,24 @@ static u32 cs_etm__mem_access(struct cs_etm_queue *etmq, u8 trace_chan_id, if (!tidq) return 0; + /* + * We've already tracked EL along side the PID in cs_etm__set_thread() + * so double check that it matches what OpenCSD thinks as well. It + * doesn't distinguish between EL0 and EL1 for this mem access callback + * so we had to do the extra tracking. Skip validation if it's any of + * the 'any' values. + */ + if (!(mem_space == OCSD_MEM_SPACE_ANY || + mem_space == OCSD_MEM_SPACE_N || mem_space == OCSD_MEM_SPACE_S)) { + if (mem_space & OCSD_MEM_SPACE_EL1N) { + /* Includes both non secure EL1 and EL0 */ + assert(tidq->el == ocsd_EL1 || tidq->el == ocsd_EL0); + } else if (mem_space & OCSD_MEM_SPACE_EL2) + assert(tidq->el == ocsd_EL2); + else if (mem_space & OCSD_MEM_SPACE_EL3) + assert(tidq->el == ocsd_EL3); + } + cpumode = cs_etm__cpu_mode(etmq, address, tidq->el); if (!thread__find_map(tidq->thread, cpumode, address, &al)) @@ -1215,8 +1234,8 @@ static inline int cs_etm__t32_instr_size(struct cs_etm_queue *etmq, { u8 instrBytes[2]; - cs_etm__mem_access(etmq, trace_chan_id, addr, - ARRAY_SIZE(instrBytes), instrBytes); + cs_etm__mem_access(etmq, trace_chan_id, addr, ARRAY_SIZE(instrBytes), + instrBytes, 0); /* * T32 instruction size is indicated by bits[15:11] of the first * 16-bit word of the instruction: 0b11101, 0b11110 and 0b11111 @@ -1407,8 +1426,8 @@ static void cs_etm__copy_insn(struct cs_etm_queue *etmq, else sample->insn_len = 4; - cs_etm__mem_access(etmq, trace_chan_id, sample->ip, - sample->insn_len, (void *)sample->insn); + cs_etm__mem_access(etmq, trace_chan_id, sample->ip, sample->insn_len, + (void *)sample->insn, 0); } u64 cs_etm__convert_sample_time(struct cs_etm_queue *etmq, u64 cs_timestamp) @@ -1961,8 +1980,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id, * so below only read 2 bytes as instruction size for T32. */ addr = end_addr - 2; - cs_etm__mem_access(etmq, trace_chan_id, addr, - sizeof(instr16), (u8 *)&instr16); + cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr16), + (u8 *)&instr16, 0); if ((instr16 & 0xFF00) == 0xDF00) return true; @@ -1977,8 +1996,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id, * +---------+---------+-------------------------+ */ addr = end_addr - 4; - cs_etm__mem_access(etmq, trace_chan_id, addr, - sizeof(instr32), (u8 *)&instr32); + cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32), + (u8 *)&instr32, 0); if ((instr32 & 0x0F000000) == 0x0F000000 && (instr32 & 0xF0000000) != 0xF0000000) return true; @@ -1994,8 +2013,8 @@ static bool cs_etm__is_svc_instr(struct cs_etm_queue *etmq, u8 trace_chan_id, * +-----------------------+---------+-----------+ */ addr = end_addr - 4; - cs_etm__mem_access(etmq, trace_chan_id, addr, - sizeof(instr32), (u8 *)&instr32); + cs_etm__mem_access(etmq, trace_chan_id, addr, sizeof(instr32), + (u8 *)&instr32, 0); if ((instr32 & 0xFFE0001F) == 0xd4000001) return true; -- 2.34.1