From patchwork Mon Jul 18 19:51:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Poirier X-Patchwork-Id: 9235191 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 10615602F0 for ; Mon, 18 Jul 2016 19:55:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 012B9205AD for ; Mon, 18 Jul 2016 19:55:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E9A0A205B0; Mon, 18 Jul 2016 19:55:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 83A92205AD for ; Mon, 18 Jul 2016 19:55:49 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bPEcR-0000Cv-UW; Mon, 18 Jul 2016 19:54:24 +0000 Received: from mail-io0-x22e.google.com ([2607:f8b0:4001:c06::22e]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bPEaB-00077C-N7 for linux-arm-kernel@lists.infradead.org; Mon, 18 Jul 2016 19:52:06 +0000 Received: by mail-io0-x22e.google.com with SMTP id m101so365697ioi.2 for ; Mon, 18 Jul 2016 12:51:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=SYD1XD2j+BB33seh1wJUt6IHxWpgrEKVjEq+jXxNDuU=; b=SWB/DTbdcLf10wo+DJZH4si3qZjopJQp6dM/i7+Xod4xiyTlx8j+ZmHsmLgEckO8Lx 3FVl4bnfY5pZP9Z40FJzhYAnzBB3V1mTg4QhmrHaIcTemSKa6GOoumxkDw1hDHi2XpTs c5/WPsWlJPKKorFcZT5UmA0vBg/QAnLL4F2VA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=SYD1XD2j+BB33seh1wJUt6IHxWpgrEKVjEq+jXxNDuU=; b=Kx0r6vl6eM8nK5BAntQFOuNtGdr0Ghjlm2fwZMSaI+8IxqvNZu/6+mF4QWYZFPtcnf cGVHs2dL73b80aJ3rXVAoWbXzt7phPjNMJzBcUgw8nh9N6I3s+7ihG52u8QnMFlEdzF9 5V1kH4a2qzOZ/PeY1owgH6q8LLrYHO7wXfoF1/3J8yIS6jYCZJTvx3VuDKD6xaU9jYlM WbNtcUKCbou/333+39TUyhBbja4L7eRGBAs8xjj+MSq9aLigkOfWnV0cAFuGkOx+4N3c dXMlwQYJYvIP1Q2U/RUxMG5D01Bu8AOmZ/w2vbRNXhxXkYWxSB+8D7UBN/yxTztXrBUE D0Lg== X-Gm-Message-State: ALyK8tL6owYVItCQOMCOr91wXj/PBmGn5YcY0MGOADSKHtTSyteN4YLD1URBTuYqrf3m4/gz X-Received: by 10.107.20.82 with SMTP id 79mr20624569iou.108.1468871502806; Mon, 18 Jul 2016 12:51:42 -0700 (PDT) Received: from t430.cg.shawcable.net (S0106002369de4dac.cg.shawcable.net. [68.147.8.254]) by smtp.gmail.com with ESMTPSA id r128sm5270676ita.6.2016.07.18.12.51.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 18 Jul 2016 12:51:42 -0700 (PDT) From: Mathieu Poirier To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 08/10] coresight: etm4x: adding configurable address range filtering Date: Mon, 18 Jul 2016 13:51:29 -0600 Message-Id: <1468871491-10997-9-git-send-email-mathieu.poirier@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1468871491-10997-1-git-send-email-mathieu.poirier@linaro.org> References: <1468871491-10997-1-git-send-email-mathieu.poirier@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160718_125204_094369_C2ECCAA9 X-CRM114-Status: GOOD ( 20.08 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alexander.shishkin@linux.intel.com, linux-kernel@vger.kernel.org, Mathieu Poirier MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds the capability to specify address ranges from the perf cmd line using the --filter option. If the IP falls within the range(s) program flow traces are generated. Signed-off-by: Mathieu Poirier --- drivers/hwtracing/coresight/coresight-etm4x.c | 128 ++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c index 9eba6d8f4633..b807333ce6a1 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.c +++ b/drivers/hwtracing/coresight/coresight-etm4x.c @@ -46,7 +46,9 @@ module_param_named(boot_enable, boot_enable, int, S_IRUGO); /* The number of ETMv4 currently registered */ static int etm4_count; static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; -static void etm4_set_default(struct etmv4_config *config); +static void etm4_set_default_config(struct etmv4_config *config); +static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, + struct perf_event *event); static void etm4_os_unlock(struct etmv4_drvdata *drvdata) { @@ -195,11 +197,14 @@ static void etm4_enable_hw(void *info) static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, struct perf_event *event) { + int ret = 0; struct etmv4_config *config = &drvdata->config; struct perf_event_attr *attr = &event->attr; - if (!attr) - return -EINVAL; + if (!attr) { + ret = -EINVAL; + goto out; + } /* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config)); @@ -211,7 +216,12 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, config->mode = ETM_MODE_EXCL_USER; /* Always start from the default config */ - etm4_set_default(config); + etm4_set_default_config(config); + + /* Configure filters specified on the perf cmd line, if any. */ + ret = etm4_set_event_filters(drvdata, event); + if (ret) + goto out; /* Go from generic option to ETMv4 specifics */ if (attr->config & BIT(ETM_OPT_CYCACC)) @@ -219,23 +229,30 @@ static int etm4_parse_event_config(struct etmv4_drvdata *drvdata, if (attr->config & BIT(ETM_OPT_TS)) config->cfg |= ETMv4_MODE_TIMESTAMP; - return 0; +out: + return ret; } static int etm4_enable_perf(struct coresight_device *csdev, struct perf_event *event) { + int ret = 0; struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); - if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) - return -EINVAL; + if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) { + ret = -EINVAL; + goto out; + } /* Configure the tracer based on the session's specifics */ - etm4_parse_event_config(drvdata, event); + ret = etm4_parse_event_config(drvdata, event); + if (ret) + goto out; /* And enable it */ etm4_enable_hw(drvdata); - return 0; +out: + return ret; } static int etm4_enable_sysfs(struct coresight_device *csdev) @@ -685,6 +702,99 @@ static void etm4_set_default(struct etmv4_config *config) etm4_set_default_filter(config); } +static int etm4_get_next_comparator(struct etmv4_drvdata *drvdata, u32 type) +{ + int nr_comparator, index = 0; + struct etmv4_config *config = &drvdata->config; + + /* + * nr_addr_cmp holds the number of comparator _pair_, so time 2 + * for the total number of comparators. + */ + nr_comparator = drvdata->nr_addr_cmp * 2; + + /* Go through the tally of comparators looking for a free one. */ + while (index < nr_comparator) { + switch (type) { + case ETM_ADDR_TYPE_RANGE: + if (config->addr_type[index] == ETM_ADDR_TYPE_NONE && + config->addr_type[index + 1] == ETM_ADDR_TYPE_NONE) + return index; + + /* Address range comparators go in pairs */ + index += 2; + break; + default: + return -EINVAL; + } + } + + /* If we are here all the comparators have been used. */ + return -ENOSPC; +} + +static int etm4_set_event_filters(struct etmv4_drvdata *drvdata, + struct perf_event *event) +{ + int i, comparator, ret = 0; + struct etmv4_config *config = &drvdata->config; + struct etm_filters *filters = event->hw.addr_filters; + + if (!filters) + goto default_filter; + + /* Sync events with what Perf got */ + perf_event_addr_filters_sync(event); + + /* + * If there are no filters to deal with simply go ahead with + * the default filter, i.e the entire address range. + */ + if (!filters->nr_filters) + goto default_filter; + + for (i = 0; i < filters->nr_filters; i++) { + struct etm_filter *filter = &filters->filter[i]; + enum etm_addr_type type = filter->type; + + /* See if a comparator is free. */ + comparator = etm4_get_next_comparator(drvdata, type); + if (comparator < 0) { + ret = comparator; + goto out; + } + + switch (type) { + case ETM_ADDR_TYPE_RANGE: + etm4_set_comparator_filter(config, + filter->start_addr, + filter->stop_addr, + comparator); + /* + * TRCVICTLR::SSSTATUS == 1, the start-stop logic is + * in the started state + */ + config->vinst_ctrl |= BIT(9); + + /* No start-stop filtering for ViewInst */ + config->vissctlr = 0x0; + break; + default: + ret = -EINVAL; + goto out; + } + } + + goto out; + + +default_filter: + etm4_set_default_filter(config); + +out: + return ret; +} + void etm4_config_trace_mode(struct etmv4_config *config) { u32 addr_acc, mode;