From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9FB431FCF6D for ; Wed, 27 Nov 2024 13:43:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714985; cv=none; b=f5FxYnlguKEw1dG0j3ZNpnfip6D6azjzprSeDhluhHI4OgC7kx8gUb2P3mGfnIQEyS2xs59DvTT2sAM/deVDvFXsE0ujXuETWWfOqS1hfwC7MzBBsJPjiZbFkMgyC56mP3fPHbfvC9Qrr9VVx4IFuxadaqKPUbU2Tf+DomPjVj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714985; c=relaxed/simple; bh=QCxyFTfD55cG3G+5pkhgCm0uoh+bT75AjY5HmMpHWLo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eaL/y+UmWeI/RAnzfMLuYnt2vWMgvd3mTb+OoW6RB2ftEiygKgCPXXfUZ5M9SmAa93rGFn1/3x+tuL/oMYg/CTl5JnqCGkgLzDY3UW8jokjbEjuqIGverG5VDfZB66Dn9pMAhyZ1U2DjRVTHiCgZRjj1+TBVxg8lNHTBNy6G9p8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=IAQL6xU7; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="IAQL6xU7" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-43494a20379so34347215e9.0 for ; Wed, 27 Nov 2024 05:43:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714981; x=1733319781; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6flL3GGiMYjVnt45/CM8ndMN3PxyC3V1rbxJWt0xHV0=; b=IAQL6xU7toJzLgtwnMmnVRFIeSKGkUAN8iBigs94OOGoSVJuJdkaDt9bZbImunJoPW /0vLvr/9j4g2v3DHj0jSREf/hxvN8GxzZydgnYLRHQNMQD3Ht5ghPMawUjC6b+v6ja5j yMlokqBRQFkCD9wMnxhfJ7mgnieSZUH8Imp5dIl2xYbSd56z++Kglm2/47tzpF32Vqvx 3h+zr3V//MFDA4UkCr71pg8psLgy8KOXLTQIbQblTvvADEOlwIa1fWugbk3fTFM7IdbI IzlAnbsyvSoLsWrvPb7VuO1t3jGjqxzI2At2cfdt7xvJGp/CJ3hpvsK0LfhR4hxDMNRF oz0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714981; x=1733319781; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6flL3GGiMYjVnt45/CM8ndMN3PxyC3V1rbxJWt0xHV0=; b=i/4iRbGbAzauBW4GnNcXCxnNKhq+7XDZ/lN8fJ5pNNFgRs3ObAL9ZX2oAnexA0jrZd YC/rfSar/UUScQ4Df4V/OtblOk8Qb/savaNO8XkrnPPyLqJ08buLKk5q2KbClUyZG58A kBVk4PHyY3CwDAoJLeeb6GaXh8dWRUx49v9TR1i/7SYXtrlEeG49tj3WxlPTj86+JrL2 CrVGQeo4sfE/aCnDAivUHXS35RqcsWM508Hro7n8iHy/8Kx/bu+MsJsKdMzc590Y6KD1 FpK+/q719bHa45u3XoPNks3levFKO39mIRqU8PWcVOvkfFfMVJxKVRyGsxAv9RvlyHN2 t1ZA== X-Forwarded-Encrypted: i=1; AJvYcCX16wl+BmDRiBaLy40B7eVed+7FSoNKTy3LwPbCAOE2XLE7uy9cDIRaGV6Xh0rIeNTdZ8cFPNHWD+C29zs=@vger.kernel.org X-Gm-Message-State: AOJu0YwIpwnEwhBHytRSjZhj23bqW75yh6phcd6x0wp0aLKxI0TQagu5 Gta0u1WH9m8Uht8hIzcnwBSoSB2iXD9NvaGkCB5+t8OpDHEwjN0EBHniPNcf5qWjZJfjXGvvKrm d X-Gm-Gg: ASbGncu93yS4k9+nnrVNr5szEqtokSq+YT40fvTvhGvB+qnrybaOyDEjZkXvrLRS74V lG7EfgrZcqIq4qPduWySbPihRuw+Lcb3VQgXaOg92X/eoG4ZO726rCoeR8aOyNnRGtVJqx6HaSV r3N5ImvVLJi/wwVZnl/89p27P9CqxFsnRUUgRiqCrH8Hj5HgBpXDtAeF8go353lPF2xgc281fYy mG9dyRkpFp9NSTr5TInjtM4xfSgtlL4S7NF0Q53tT2E8wP5MZ0Q X-Google-Smtp-Source: AGHT+IE81ldtp7TNEaQ7Kf6Q2P7l7qX6168CXrfX0iV6R8FUmrLn9JA7WKKEtOJCz2ZPJ2u+EHCSKg== X-Received: by 2002:a05:6000:2d12:b0:382:3afd:1273 with SMTP id ffacd0b85a97d-385c6ec0b21mr2018976f8f.30.1732714980686; Wed, 27 Nov 2024 05:43:00 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.42.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:00 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 1/9] coresight: config: Add configuration table processing funtionality Date: Wed, 27 Nov 2024 13:42:48 +0000 Message-Id: <20241127134256.2254851-2-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a CoreSight configuration table format to allow dynamic configuration load at runtime. This allows provision of portable configurations that are not dependent on compilation into a kernel module. Define a compact binary table format for configurations and features and provide a reader for that format that will expand and populate the internal configuration and feature structures use by the driver infrastructure. Adds API to read tables and convert to internal structures to load into coresight infrastructure. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- drivers/hwtracing/coresight/Makefile | 3 +- .../coresight/coresight-config-table.c | 427 ++++++++++++++++++ .../coresight/coresight-config-table.h | 146 ++++++ .../hwtracing/coresight/coresight-config.h | 21 + 4 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 drivers/hwtracing/coresight/coresight-config-table.c create mode 100644 drivers/hwtracing/coresight/coresight-config-table.h diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/cores= ight/Makefile index 4ba478211b31..a5c5b8bd61cb 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -26,7 +26,8 @@ obj-$(CONFIG_CORESIGHT) +=3D coresight.o coresight-y :=3D coresight-core.o coresight-etm-perf.o coresight-platform= .o \ coresight-sysfs.o coresight-syscfg.o coresight-config.o \ coresight-cfg-preload.o coresight-cfg-afdo.o \ - coresight-syscfg-configfs.o coresight-trace-id.o + coresight-syscfg-configfs.o coresight-trace-id.o \ + coresight-config-table.o obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) +=3D coresight-tmc.o coresight-tmc-y :=3D coresight-tmc-core.o coresight-tmc-etf.o \ coresight-tmc-etr.o diff --git a/drivers/hwtracing/coresight/coresight-config-table.c b/drivers= /hwtracing/coresight/coresight-config-table.c new file mode 100644 index 000000000000..0a8f017d76d2 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-table.c @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include "coresight-config-table.h" + +#define cscfg_extract_u64(val64) { \ + val64 =3D *(u64 *)(buffer + used); \ + used +=3D sizeof(u64); \ + } + +#define cscfg_extract_u32(val32) { \ + val32 =3D *(u32 *)(buffer + used); \ + used +=3D sizeof(u32); \ + } + +#define cscfg_extract_u16(val16) { \ + val16 =3D *(u16 *)(buffer + used); \ + used +=3D sizeof(u16); \ + } + +#define cscfg_extract_u8(val8) { \ + val8 =3D *(buffer + used); \ + used++; \ + } + +static int cscfg_table_read_hdr(const u8 *buffer, const int buflen, int *b= uf_used, + struct cscfg_table_header *hdr) +{ + /* table header always at the start of the buffer */ + int used =3D 0; + + if (buflen < sizeof(struct cscfg_table_header)) + return -EINVAL; + + cscfg_extract_u32(hdr->magic_version); + if (hdr->magic_version !=3D CSCFG_TABLE_MAGIC_VERSION) + return -EINVAL; + + cscfg_extract_u16(hdr->length); + if (hdr->length > buflen) + return -EINVAL; + + cscfg_extract_u16(hdr->nr_configs); + cscfg_extract_u16(hdr->nr_features); + + *buf_used =3D used; + return 0; +} + +static int cscfg_table_read_elem_hdr(const u8 *buffer, const int buflen, i= nt *buf_used, + struct cscfg_table_elem_header *elem_hdr) +{ + int used =3D *buf_used; + + if ((buflen - used) < (sizeof(u16) + sizeof(u8))) + return -EINVAL; + + /* read length and check enough buffer remains for this element */ + elem_hdr->elem_length =3D *(u16 *)(buffer + used); + if ((buflen - used) < elem_hdr->elem_length) + return -EINVAL; + /* don't use extract fn as we update used _after_ the comparison */ + used +=3D sizeof(u16); + + /* read type and validate */ + cscfg_extract_u8(elem_hdr->elem_type); + if ((elem_hdr->elem_type < CSCFG_TABLE_ELEM_TYPE_FEAT) || + (elem_hdr->elem_type > CSCFG_TABLE_ELEM_TYPE_CFG)) + return -EINVAL; + + *buf_used =3D used; + return 0; +} + +static int cscfg_table_read_elem_str(const u8 *buffer, const int buflen, i= nt *buf_used, + struct cscfg_table_elem_str *elem_str) +{ + int used =3D *buf_used; + + if ((buflen - used) < sizeof(u16)) + return -EINVAL; + + cscfg_extract_u16(elem_str->str_len); + + if ((buflen - used) < elem_str->str_len) + return -EINVAL; + + /* check for 0 termination */ + if (buffer[used + (elem_str->str_len - 1)] !=3D 0) + return -EINVAL; + + elem_str->str =3D kstrdup((char *)(buffer + used), GFP_KERNEL); + used +=3D elem_str->str_len; + + *buf_used =3D used; + return 0; +} + +static int cscfg_table_alloc_desc_arrays(struct cscfg_table_load_descs *de= sc_arrays, + int nr_features, int nr_configs) +{ + /* arrays are 0 terminated - nr_configs & nr_features elements */ + desc_arrays->config_descs =3D kcalloc(nr_configs + 1, sizeof(struct cscf= g_config_desc *), + GFP_KERNEL); + if (!desc_arrays->config_descs) + return -ENOMEM; + desc_arrays->feat_descs =3D kcalloc(nr_features + 1, sizeof(struct cscfg_= feature_desc *), + GFP_KERNEL); + if (!desc_arrays->feat_descs) + return -ENOMEM; + return 0; +} + +/* free up the data allocated to a config desc */ +static void cscfg_table_free_config_desc(struct cscfg_config_desc *config_= desc) +{ + int i; + + if (!config_desc) + return; + + /* free presets */ + kfree(config_desc->presets); + + /* free feat ref strings */ + if (config_desc->nr_feat_refs) { + /* each string */ + for (i =3D 0; i < config_desc->nr_feat_refs; i++) + kfree(config_desc->feat_ref_names[i]); + + /* and the char * array */ + kfree(config_desc->feat_ref_names); + } + + /* next the strings */ + kfree(config_desc->name); + kfree(config_desc->description); + + /* finally the struct itself */ + kfree(config_desc); +} + +static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen= , int *buf_used, + struct cscfg_table_load_descs *desc_arrays, + const int cfg_index) +{ + struct cscfg_table_elem_header elem_hdr; + struct cscfg_table_elem_str elem_str; + struct cscfg_config_desc *config_desc; + int used =3D *buf_used, nr_preset_vals, nr_preset_bytes, i; + int err =3D 0; + u64 *presets; + + /* + * read the header - if not config, then don't update buf_used + * pointer on return + */ + err =3D cscfg_table_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + if (elem_hdr.elem_type !=3D CSCFG_TABLE_ELEM_TYPE_CFG) + return 0; + + /* we have a config - allocate the descriptor */ + config_desc =3D kzalloc(sizeof(struct cscfg_config_desc), GFP_KERNEL); + if (!config_desc) + return -ENOMEM; + + /* read the name string */ + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->name =3D elem_str.str; + + /* allocate load name if not set */ + if (!desc_arrays->load_name) + desc_arrays->load_name =3D kstrdup(config_desc->name, GFP_KERNEL); + + /* read the description string */ + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->description =3D elem_str.str; + + /* read in some values */ + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + cscfg_extract_u16(config_desc->nr_presets); + cscfg_extract_u32(config_desc->nr_total_params); + cscfg_extract_u16(config_desc->nr_feat_refs); + + /* read the array of 64bit presets if present */ + nr_preset_vals =3D config_desc->nr_total_params * config_desc->nr_presets; + if (nr_preset_vals) { + presets =3D kcalloc(nr_preset_vals, sizeof(u64), GFP_KERNEL); + if (!presets) + return -ENOMEM; + + nr_preset_bytes =3D sizeof(u64) * nr_preset_vals; + if ((buflen - used) < nr_preset_bytes) + return -EINVAL; + + memcpy(presets, (buffer + used), nr_preset_bytes); + config_desc->presets =3D presets; + used +=3D nr_preset_bytes; + } + + /* read the array of feature names referenced by the config */ + if (config_desc->nr_feat_refs) { + config_desc->feat_ref_names =3D kcalloc(config_desc->nr_feat_refs, + sizeof(char *), GFP_KERNEL); + if (!config_desc->feat_ref_names) + return -ENOMEM; + + for (i =3D 0; i < config_desc->nr_feat_refs; i++) { + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + config_desc->feat_ref_names[i] =3D elem_str.str; + } + } + + desc_arrays->config_descs[cfg_index] =3D config_desc; + *buf_used =3D used; + return 0; +} + +static int cscfg_table_read_elem_param(const u8 *buffer, const int buflen,= int *buf_used, + struct cscfg_parameter_desc *param_desc) +{ + struct cscfg_table_elem_str elem_str; + int err =3D 0, used =3D *buf_used; + + /* parameter name */ + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + param_desc->name =3D elem_str.str; + + /* parameter value */ + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + cscfg_extract_u64(param_desc->value); + + *buf_used =3D used; + return err; +} + +static void cscfg_table_free_feat_desc(struct cscfg_feature_desc *feat_des= c) +{ + if (!feat_desc) + return; + + /* free up the register descriptor array */ + kfree(feat_desc->regs_desc); + + /* free up the parameters array */ + kfree(feat_desc->params_desc); + + /* name and description strings */ + kfree(feat_desc->name); + kfree(feat_desc->description); + + /* finally the struct itself */ + kfree(feat_desc); +} + +static int cscfg_table_read_elem_feature(const u8 *buffer, const int bufle= n, int *buf_used, + struct cscfg_table_load_descs *desc_arrays, + const int feat_idx) +{ + struct cscfg_table_elem_header elem_hdr; + struct cscfg_table_elem_str elem_str; + struct cscfg_feature_desc *feat_desc; + struct cscfg_regval_desc *p_reg_desc; + int used =3D *buf_used, err, i, nr_regs_bytes; + u32 val32; + + /* allocate the feature descriptor object */ + feat_desc =3D kzalloc(sizeof(struct cscfg_feature_desc), GFP_KERNEL); + if (!feat_desc) + return -ENOMEM; + + /* read and check the element header */ + err =3D cscfg_table_read_elem_hdr(buffer, buflen, &used, &elem_hdr); + if (err) + return err; + + if (elem_hdr.elem_type !=3D CSCFG_TABLE_ELEM_TYPE_FEAT) + return -EINVAL; + + /* read the feature name */ + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + feat_desc->name =3D elem_str.str; + + /* allocate load name if not set previously by config */ + if (!desc_arrays->load_name) + desc_arrays->load_name =3D kstrdup(feat_desc->name, GFP_KERNEL); + + /* read the description string */ + err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); + if (err) + return err; + feat_desc->description =3D elem_str.str; + + /* + * read in some values + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + */ + cscfg_extract_u32(feat_desc->match_flags); + cscfg_extract_u16(feat_desc->nr_regs); + cscfg_extract_u16(feat_desc->nr_params); + + /* register descriptors - 32 bit + 64 bit value */ + if (feat_desc->nr_regs) { + nr_regs_bytes =3D ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs); + if ((buflen - used) < nr_regs_bytes) + return -EINVAL; + feat_desc->regs_desc =3D kcalloc(feat_desc->nr_regs, + sizeof(struct cscfg_regval_desc), GFP_KERNEL); + if (!feat_desc->regs_desc) + return -ENOMEM; + + for (i =3D 0; i < feat_desc->nr_regs; i++) { + cscfg_extract_u32(val32); + p_reg_desc =3D (struct cscfg_regval_desc *)&feat_desc->regs_desc[i]; + CSCFG_TABLE_U32_TO_REG_DESC_INFO(val32, p_reg_desc); + cscfg_extract_u64(feat_desc->regs_desc[i].val64); + } + } + + /* parameter descriptors - string + 64 bit value */ + if (feat_desc->nr_params) { + feat_desc->params_desc =3D kcalloc(feat_desc->nr_params, + sizeof(struct cscfg_parameter_desc), GFP_KERNEL); + if (!feat_desc->params_desc) + return -ENOMEM; + for (i =3D 0; i < feat_desc->nr_params; i++) { + err =3D cscfg_table_read_elem_param(buffer, buflen, &used, + &feat_desc->params_desc[i]); + if (err) + return err; + } + } + + desc_arrays->feat_descs[feat_idx] =3D feat_desc; + *buf_used =3D used; + return 0; +} + +/* + * Read the table from a buffer and create the internal configuration and + * feature descriptors to load into the cscfg system + */ +int cscfg_table_read_buffer(const u8 *buffer, const int buflen, + struct cscfg_table_load_descs *desc_arrays) +{ + struct cscfg_table_header hdr; + int used =3D 0, err, i; + + /* read in the table header */ + err =3D cscfg_table_read_hdr(buffer, buflen, &used, &hdr); + if (err) + return err; + + /* allocate the memory for the descriptor pointer arrays */ + err =3D cscfg_table_alloc_desc_arrays(desc_arrays, hdr.nr_features, hdr.n= r_configs); + if (err) + return err; + + /* read elements */ + + /* first elements are configurations */ + for (i =3D 0; i < hdr.nr_configs; i++) { + err =3D cscfg_table_read_elem_config(buffer, buflen, &used, desc_arrays,= i); + if (err) + return err; + } + + /* now read and populate all the feature descriptors */ + for (i =3D 0; i < hdr.nr_features; i++) { + err =3D cscfg_table_read_elem_feature(buffer, buflen, &used, desc_arrays= , i); + if (err) + return err; + } + return 0; +} + +/* + * Need to free up the dynamically allocated descriptor arrays on unload + * as the memory used could be significant if many configurations are load= ed + * and unloaded while the machine is operational. + * + * This frees up all the memory allocated by config during the load proces= s. + */ +void cscfg_table_free_load_descs(struct cscfg_table_load_descs *desc_array= s) +{ + int i =3D 0; + + if (!desc_arrays) + return; + + /* free up each of the config descriptors */ + while (desc_arrays->config_descs[i]) { + cscfg_table_free_config_desc(desc_arrays->config_descs[i]); + i++; + } + + /* free up each of the feature descriptors */ + i =3D 0; + while (desc_arrays->feat_descs[i]) { + cscfg_table_free_feat_desc(desc_arrays->feat_descs[i]); + i++; + } + + /* finally free up the load descs pointer arrays */ + kfree(desc_arrays->config_descs); + kfree(desc_arrays->feat_descs); + kfree(desc_arrays->load_name); +} diff --git a/drivers/hwtracing/coresight/coresight-config-table.h b/drivers= /hwtracing/coresight/coresight-config-table.h new file mode 100644 index 000000000000..2cd8fb0630e2 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-table.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_TABLE_H +#define _CORESIGHT_CORESIGHT_CONFIG_TABLE_H + +#include + +#include "coresight-config.h" + +/* + * Configurations and features can be dynamically loaded at runtime + * using a table format that is converted on read into the internal + * structures used by the cscfg infrastructure. + * + * Table structure - for loading configuration(s) + feature(s) + * from configfs or other external sources. + * + * [cscfg_table_header] - mandatory + * [CONFIG_ELEM] * [cscfg_table_header.nr_configs] - optional. + * [FEATURE_ELEM] * [cscfg_table_header.nr_features] - optional. + * + * Table valid if it has both config(s) and feature(s), only config(s) + * or only feature(s). + * + * Invalid table if no config or features. + * + * Structure for [CONFIG_ELEM]: + * + * [cscfg_table_elem_header] - header length value to end of feature strin= gs. + * [cscfg_table_elem_str] - name of the configuration + * [cscfg_table_elem_str] - description of configuration + * [u16 value - nr_presets] - number of sets of presets supplied + * [u32 value - nr_total_params] - total of all params in referenced featu= res + * [u16 value - nr_feat_refs] - number of features selected by this config= uration + * [u64 values] * (nr_presets * nr_total_params) + * [cscfg_table_elem_str] * nr_feat_refs - names of features selected by c= onfiguration. + * + * A configuration must reference at least one feature. + * Referenced features may be in this table, or have been loaded previous= ly. + * + * Structure for a [FEATURE_ELEM] + * + * [cscfg_table_elem_header] - header length is total bytes to end of para= m structures. + * [cscfg_table_elem_str] - feature name. + * [cscfg_table_elem_str] - feature description. + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + * [cscfg_regval_desc struct] * nr_regs + * [PARAM_ELEM] * nr_params + * + * Structure for [PARAM_ELEM] + * + * [cscfg_table_elem_str] - parameter name. + * [u64 value: param_value] - initial value. + */ + +/* major element types - configurations and features */ + +#define CSCFG_TABLE_ELEM_TYPE_FEAT 0x1 +#define CSCFG_TABLE_ELEM_TYPE_CFG 0x2 + +#define CSCFG_TABLE_MAGIC_VERSION 0xC5CF0001 + +#define CSCFG_TABLE_U32_TO_REG_DESC_INFO(val32, p_desc) \ + { \ + p_desc->type =3D (val32 >> 24) & 0xFF; \ + p_desc->offset =3D (val32 >> 12) & 0xFFF; \ + p_desc->hw_info =3D val32 & 0xFFF; \ + } + +#define CSCFG_TABLE_REG_DESC_INFO_TO_U32(val32, p_desc) \ + { \ + val32 =3D p_desc->hw_info & 0xFFF; \ + val32 |=3D ((p_desc->offset & 0xFFF) << 12); \ + val32 |=3D ((p_desc->type & 0xFF) << 24); \ + } + +/* + * Define a maximum size for any configuration table. + * + * Use a value that will reasonably cover all the usable & programmable + * registers in an ETM, the most complex device we have. + * + * This may also be used for the binary attributes in configfs which need = a max + * size, as an internal buffer is declared, and will not be exceeded to pr= event + * kernel OOM errors / attacks. + * + */ +#define CSCFG_TABLE_MAXSIZE SZ_16K + +/* limit string sizes - used for descriptions and names. */ +#define CSCFG_TABLE_STR_MAXSIZE SZ_1K + +/** + * Table header. + * + * @magic_version: magic number / version for table format. + * @length : total length of all data in the table. + * @nr_configs : total number of configs in the table. + * @nr_features : total number of features in the table. + */ +struct cscfg_table_header { + u32 magic_version; + u16 length; + u16 nr_configs; + u16 nr_features; +}; + +/** + * element header + * + * @elem_length: total length of this element + * @elem_type : type of this element - one of CSCFG_TABLE_ELEM_TYPE.. def= ines. + */ +struct cscfg_table_elem_header { + u16 elem_length; + u8 elem_type; +}; + +/** + * string table element. + * + * @str_len: length of string buffer including 0 terminator + * @str : string buffer - 0 terminated. + */ +struct cscfg_table_elem_str { + u16 str_len; + char *str; +}; + +/* + * Read a configuration programming table from the buffer and create the + * structures needed to load into the cscfg system + */ +int cscfg_table_read_buffer(const u8 *buffer, const int buflen, + struct cscfg_table_load_descs *desc_arrays); + +/* on unload we need to free up memory allocated on read */ +void cscfg_table_free_load_descs(struct cscfg_table_load_descs *desc_array= s); + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_TABLE_H */ diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtra= cing/coresight/coresight-config.h index 6ba013975741..ea3aaf0d129b 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -85,6 +85,27 @@ struct cscfg_regval_desc { }; }; =20 +/** + * Dynamically loaded descriptor arrays. + * + * For builtin or module loaded configurations / features these are + * statically defined at compile time. + + * For a dynamic load at runtime, using a config table, (e.g. load from + * configfs) we create the arrays dynamically so need a structure to + * manage these. + * + * @config_descs: array of config descriptor pointers. + * @feat_descs: array of feature descriptor pointers. + * @load_name: user readable name which may be used to unload later. + * Will be name of first config if present, or first feature. + */ +struct cscfg_table_load_descs { + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; + char *load_name; +}; + /** * Device feature descriptor - combination of registers and parameters to * program a device to implement a specific complex function. --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CE2C1FCF74 for ; Wed, 27 Nov 2024 13:43:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714985; cv=none; b=msDe0e27R8b4frGERmFycEx0Tjgz+zevl6K+zz9ukuBJxRixcZEVh1ZVjty4BhA1OV3xUblhHHC9yaucicJupotaPHumyGZxbD6vLEarY4dT8o8Phw4h2mKaL9QB8XgI/NIxcSpoxdhiPDeXx5O0VRKM0c/MlsHgO9P4974z/Eg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714985; c=relaxed/simple; bh=d9O4E1eCJUeYe6MNqeJOsmL4aDt7l0VgmbNT/ZslYvw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QB4BRv34UJwcBF5dyb2uLcVLPdDuGulWBgQCP6nqUZKn2r5dAb5o7V2dYZaJDtOKafM688Rkd7hY9qiWk3GV+6nn4a2aq1G7Bvw6Knue0bDAywstG7o16nqakSvBkXV6Uk81yMjnLLd/0rbIuvK4O6snjBbFR/GZU4czwPAAjX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=TmAcDJRz; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="TmAcDJRz" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-434aa472617so7087625e9.3 for ; Wed, 27 Nov 2024 05:43:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714982; x=1733319782; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pyZuZfXEwO8d6lRLKEFPF6ZWKWzWzABGPH32iU5IC2w=; b=TmAcDJRzPfy5d980IyAWj56OS4xtTu5uSgen3Miz/3Ao4EgbmAZ7SJbR7IEgCeE3j1 qcoTMFyT3sQgeX13Pfwu1uxjF5bg10TsmCRrMWCj3lMDIPcwmsOZPjqS+ar5xlO3xsLJ I71XROuyYnJAQ+/F++9QFihSM3t8LEAtLytcFrcy56lgFqq0BRvt5ibkGm+dBEmxQ2Nd CWIDby74m6XkBmmeKVPuTu5nMBonXG5KLgZnltIilhJfN++XDPVYlpHgfxr6t0JlhxYe IRJKYJwITsqyJLZYOeFUuXGgALA76tZMTyVfACP7TcByw7UydHGtb6SIheww1pi/qYJ6 mu4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714982; x=1733319782; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pyZuZfXEwO8d6lRLKEFPF6ZWKWzWzABGPH32iU5IC2w=; b=g8Q6C012PQS5ABnpS8rtsSPi4tI31hkPPW1/Bi+OV1edllJfgjtYvfKSzv0IhEK3DN jEGDAyO+TpUIwMal695kvQjvJsuSx6ULozA+5FVOM9uMv2e+AG/Ppi4qAqJfD56BcWpl k2AsfEOM7TWygPdiu1mq3fiNewkz8Bckfa5uoPI53m/I0yi46/7mWfaFVQ2gkInri3ms VJhDDYG6UG5VnqV/Yi2eXL8TqEPDl3LbY3oz1TPWjSNiWwkDWWfeDVW9qhosDyNTkTYV HCOtTGOQTJC7/JXWDnayBlm8wHA7EjnWkRxo0CKK0rl4HCYuU+2TZxkU+zep80BE0kR1 OPcw== X-Forwarded-Encrypted: i=1; AJvYcCUehIpBMLPHYHnxKm8bPNqAyJ0EkoiZLwW0lV7I1B68fqTRECF/tYZBEpdxYdm/a+8BW1P5FbI5nY3c55k=@vger.kernel.org X-Gm-Message-State: AOJu0Ywso+MKJP05hydijZmF2ZAGOWXsriTU7iFhdZMyOtq2q14CAEd/ X/z8nyuyQuAOS3gFmVzxy+5EFWcixdgbcCKba8gdDy8ocAelhn4nqVt1EiNUf4w= X-Gm-Gg: ASbGncss0Y5fRI4MnBg5hNVGfvq/bb3QDbDw7TNduNFpqcgPQvwa/BgeWEgMa6EL63a ykg+aFPqFZM4S1u0biviXurT0tgB9FCw9C3DKkXJc0zg8TpRIHnRvYRJ1B17QHf0ixEy4XH5bJb sCgAKopIsSORZFvt5sp7kY9Pq4uLUxTePNRAPjmSibgq3XAuyxspqDmvS9vU4taNK4i2EQeXKPk ieC13tHBYbr8eq47k+lso5LIMGMjafCmU+i/fMjhFS6jdtz/3t8 X-Google-Smtp-Source: AGHT+IGBVYI2t/KGowZk4skZcgBiYypH1fP6FHAu95XaFsNOk9JsQ26I9KCwHiJ4umfksH9uVkQHgw== X-Received: by 2002:a05:600c:6d46:b0:434:a5d1:9917 with SMTP id 5b1f17b1804b1-434a9de4533mr23641915e9.21.1732714981728; Wed, 27 Nov 2024 05:43:01 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:01 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 2/9] coresight: configfs: Update memory allocation / free for configfs elements Date: Wed, 27 Nov 2024 13:42:49 +0000 Message-Id: <20241127134256.2254851-3-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previously, the objects backing the configfs directories and files were created using devm managed memory on the coresight device. Now we are adding configfs load/unload, configurations can be loaded many times over the lifetime of the device, so it is more appropriate to use normally allocated and freed memory. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-syscfg-configfs.c | 119 +++++++++++++----- 1 file changed, 88 insertions(+), 31 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/driv= ers/hwtracing/coresight/coresight-syscfg-configfs.c index 433ede94dd63..6e8c8db52d39 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -14,7 +14,7 @@ static inline struct config_item_type *cscfg_create_ci_ty= pe(void) { struct config_item_type *ci_type; =20 - ci_type =3D devm_kzalloc(cscfg_device(), sizeof(*ci_type), GFP_KERNEL); + ci_type =3D kzalloc(sizeof(*ci_type), GFP_KERNEL); if (ci_type) ci_type->ct_owner =3D THIS_MODULE; =20 @@ -175,6 +175,19 @@ static struct config_item_type cscfg_config_preset_typ= e =3D { .ct_attrs =3D cscfg_config_preset_attrs, }; =20 + +/* walk list of presets and free the previously allocated memory */ +static void cscfg_destroy_preset_groups(struct config_group *cfg_view_grou= p) +{ + struct cscfg_fs_preset *cfg_fs_preset; + struct config_group *p_group; + + list_for_each_entry(p_group, &cfg_view_group->default_groups, default_gro= ups) { + cfg_fs_preset =3D container_of(p_group, struct cscfg_fs_preset, group); + kfree(cfg_fs_preset); + } +} + static int cscfg_add_preset_groups(struct cscfg_fs_config *cfg_view) { int preset_num; @@ -186,11 +199,12 @@ static int cscfg_add_preset_groups(struct cscfg_fs_co= nfig *cfg_view) return 0; =20 for (preset_num =3D 1; preset_num <=3D config_desc->nr_presets; preset_nu= m++) { - cfg_fs_preset =3D devm_kzalloc(cscfg_device(), - sizeof(struct cscfg_fs_preset), GFP_KERNEL); + cfg_fs_preset =3D kzalloc(sizeof(struct cscfg_fs_preset), GFP_KERNEL); =20 - if (!cfg_fs_preset) + if (!cfg_fs_preset) { + cscfg_destroy_preset_groups(&cfg_view->group); return -ENOMEM; + } =20 snprintf(name, CONFIGFS_ITEM_NAME_LEN, "preset%d", preset_num); cfg_fs_preset->preset_num =3D preset_num; @@ -204,14 +218,10 @@ static int cscfg_add_preset_groups(struct cscfg_fs_co= nfig *cfg_view) =20 static struct config_group *cscfg_create_config_group(struct cscfg_config_= desc *config_desc) { - struct cscfg_fs_config *cfg_view; - struct device *dev =3D cscfg_device(); + struct cscfg_fs_config *cfg_view =3D NULL; int err; =20 - if (!dev) - return ERR_PTR(-EINVAL); - - cfg_view =3D devm_kzalloc(dev, sizeof(struct cscfg_fs_config), GFP_KERNEL= ); + cfg_view =3D kzalloc(sizeof(struct cscfg_fs_config), GFP_KERNEL); if (!cfg_view) return ERR_PTR(-ENOMEM); =20 @@ -220,12 +230,21 @@ static struct config_group *cscfg_create_config_group= (struct cscfg_config_desc * =20 /* add in a preset dir for each preset */ err =3D cscfg_add_preset_groups(cfg_view); - if (err) + if (err) { + kfree(cfg_view); return ERR_PTR(err); - + } return &cfg_view->group; } =20 +static void cscfg_destroy_config_group(struct config_group *group) +{ + struct cscfg_fs_config *cfg_view =3D container_of(group, struct cscfg_fs_= config, group); + + cscfg_destroy_preset_groups(&cfg_view->group); + kfree(cfg_view); +} + /* attributes for features view */ =20 static ssize_t cscfg_feat_description_show(struct config_item *item, char = *page) @@ -314,6 +333,17 @@ static struct config_item_type cscfg_param_view_type = =3D { .ct_attrs =3D cscfg_param_view_attrs, }; =20 +/* walk the list of default groups - which were set as param items and rem= ove */ +static void cscfg_destroy_params_group_items(struct config_group *params_g= roup) +{ + struct cscfg_fs_param *param_item; + struct config_group *p_group; + + list_for_each_entry(p_group, ¶ms_group->default_groups, default_group= s) { + param_item =3D container_of(p_group, struct cscfg_fs_param, group); + kfree(param_item); + } +} /* * configfs has far less functionality provided to add attributes dynamica= lly than sysfs, * and the show and store fns pass the enclosing config_item so the actual= attribute cannot @@ -322,15 +352,16 @@ static struct config_item_type cscfg_param_view_type = =3D { static int cscfg_create_params_group_items(struct cscfg_feature_desc *feat= _desc, struct config_group *params_group) { - struct device *dev =3D cscfg_device(); struct cscfg_fs_param *param_item; int i; =20 /* parameter items - as groups with default_value attribute */ for (i =3D 0; i < feat_desc->nr_params; i++) { - param_item =3D devm_kzalloc(dev, sizeof(struct cscfg_fs_param), GFP_KERN= EL); - if (!param_item) + param_item =3D kzalloc(sizeof(struct cscfg_fs_param), GFP_KERNEL); + if (!param_item) { + cscfg_destroy_params_group_items(params_group); return -ENOMEM; + } param_item->feat_desc =3D feat_desc; param_item->param_idx =3D i; config_group_init_type_name(¶m_item->group, @@ -343,27 +374,22 @@ static int cscfg_create_params_group_items(struct csc= fg_feature_desc *feat_desc, =20 static struct config_group *cscfg_create_feature_group(struct cscfg_featur= e_desc *feat_desc) { - struct cscfg_fs_feature *feat_view; - struct config_item_type *params_group_type; + struct cscfg_fs_feature *feat_view =3D NULL; + struct config_item_type *params_group_type =3D NULL; struct config_group *params_group =3D NULL; - struct device *dev =3D cscfg_device(); - int item_err; - - if (!dev) - return ERR_PTR(-EINVAL); + int err =3D -ENOMEM; =20 - feat_view =3D devm_kzalloc(dev, sizeof(struct cscfg_fs_feature), GFP_KERN= EL); + feat_view =3D kzalloc(sizeof(struct cscfg_fs_feature), GFP_KERNEL); if (!feat_view) return ERR_PTR(-ENOMEM); =20 if (feat_desc->nr_params) { - params_group =3D devm_kzalloc(dev, sizeof(struct config_group), GFP_KERN= EL); + params_group =3D kzalloc(sizeof(struct config_group), GFP_KERNEL); if (!params_group) - return ERR_PTR(-ENOMEM); - + goto exit_err_free_mem; params_group_type =3D cscfg_create_ci_type(); if (!params_group_type) - return ERR_PTR(-ENOMEM); + goto exit_err_free_mem; } =20 feat_view->feat_desc =3D feat_desc; @@ -373,11 +399,36 @@ static struct config_group *cscfg_create_feature_grou= p(struct cscfg_feature_desc if (params_group) { config_group_init_type_name(params_group, "params", params_group_type); configfs_add_default_group(params_group, &feat_view->group); - item_err =3D cscfg_create_params_group_items(feat_desc, params_group); - if (item_err) - return ERR_PTR(item_err); + err =3D cscfg_create_params_group_items(feat_desc, params_group); + if (err) + goto exit_err_free_mem; } return &feat_view->group; + +exit_err_free_mem: + kfree(feat_view); + kfree(params_group_type); + kfree(params_group); + return ERR_PTR(err); +} + +static void cscfg_destroy_feature_group(struct config_group *feat_group) +{ + struct cscfg_fs_feature *feat_view; + struct config_group *params_group =3D NULL; + + feat_view =3D container_of(feat_group, struct cscfg_fs_feature, group); + + /* params group is the first item on the default group list */ + if (!list_empty(&feat_group->default_groups)) { + params_group =3D list_first_entry(&feat_group->default_groups, + struct config_group, default_groups); + cscfg_destroy_params_group_items(params_group); + /* free the item type, then the group */ + kfree(params_group->cg_item.ci_type); + kfree(params_group); + } + kfree(feat_view); } =20 static struct config_item_type cscfg_configs_type =3D { @@ -403,6 +454,8 @@ int cscfg_configfs_add_config(struct cscfg_config_desc = *config_desc) err =3D configfs_register_group(&cscfg_configs_grp, new_group); if (!err) config_desc->fs_group =3D new_group; + else + cscfg_destroy_config_group(new_group); return err; } =20 @@ -410,6 +463,7 @@ void cscfg_configfs_del_config(struct cscfg_config_desc= *config_desc) { if (config_desc->fs_group) { configfs_unregister_group(config_desc->fs_group); + cscfg_destroy_config_group(config_desc->fs_group); config_desc->fs_group =3D NULL; } } @@ -434,9 +488,11 @@ int cscfg_configfs_add_feature(struct cscfg_feature_de= sc *feat_desc) new_group =3D cscfg_create_feature_group(feat_desc); if (IS_ERR(new_group)) return PTR_ERR(new_group); - err =3D configfs_register_group(&cscfg_features_grp, new_group); + err =3D configfs_register_group(&cscfg_features_grp, new_group); if (!err) feat_desc->fs_group =3D new_group; + else + cscfg_destroy_feature_group(new_group); return err; } =20 @@ -444,6 +500,7 @@ void cscfg_configfs_del_feature(struct cscfg_feature_de= sc *feat_desc) { if (feat_desc->fs_group) { configfs_unregister_group(feat_desc->fs_group); + cscfg_destroy_feature_group(feat_desc->fs_group); feat_desc->fs_group =3D NULL; } } --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB8D81FCFCE for ; Wed, 27 Nov 2024 13:43:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714988; cv=none; b=nMfyRhv3pZyhTlGz/m0yEOLilLQPEFrlNyVcv1j4Bfi5KL3aZSe7+wmxemr21FqfbS/jfBtrhcc+hANE2FCQ6V8o/F9wJKuRGQE8SWiGVocAOeJjCzRhh1NcpVV60998Ooyyny3aO+fngVHOtxgjS/hlRFeXGA1Umn/mfQIsxwk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714988; c=relaxed/simple; bh=vukTZa9XOwMb5eNo/a6kUVG96iSGKafAmMoX92L81fU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Pne+DcApbT7s0N9WP6dC64dXpdQ5kn8h3GZyMsryQeUDpF4M9LBe4FqVB9VR7aG3taG8nFH5CKpHMworDYhqTDZvbjjBe+Rvn/O5ViTu5RmJg9d3SYaYrQAQbL7sysFStOf0ywKTikqUD8yEDsiSkfkokYN4MlxS2SuaAN20tNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=L99asXYp; arc=none smtp.client-ip=209.85.221.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="L99asXYp" Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-3824a089b2cso4139390f8f.1 for ; Wed, 27 Nov 2024 05:43:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714984; x=1733319784; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8ITMOLuXbwxTSugO6IH6IP9VkXl8XSoFNARYxodcSSA=; b=L99asXYpP1FZ17qXQ8BKit5psujpRKdHcX4izX738Mz0f8yEUUJpnK8j343/Cj/8kh ea5aUExNMG/MzjLKAZe2ovM5qxFfdk41PtgOs9qzGyccxxyziqmcU24Eys1js+RjYI0+ EwEyu+fyr0rlVhxk/qDdvQA/azLhsk/5kBXkRA6l0KlxqIdJKjT8EJ3AbmqKL/AEBRp8 eZJv8Fqa4GlBbWJJkITsWPapEm+Hx5W+Tzm8ZuQseeu/ae6K4ZIGNRD6TmmzLyf51Bo2 f8M27iUA/R/Tp+mh/MbaRtkHub/OOG29w4kmNMO/CtWbw21cd3Xwmwp/BKePaehwDydW usrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714984; x=1733319784; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8ITMOLuXbwxTSugO6IH6IP9VkXl8XSoFNARYxodcSSA=; b=J9AlzwbLN1eJdeRmeXLZQi8v3joAuKKsvxe+xQnaKts2b0W4p4kN9gFxKSMVlLrhVd ru54ydLUmwHyf0n1uzqm7usCI+CTAGvfdCjsqk2isNstT89NMJK5GMNCAp5sdsvOsXzo TfdbFZgD7Qz/KNz4KKy68d5awJvypgVo5MZC9doYjWNLNmhnpdVBYet13QnTnEkK2P/S 9+S+jJE9R6wzS2f4k8tfXam2yPmklwBOgcbAwC6W5Ge3dtPFG/YVBJoomjTRBIV6Q9Gz AxpVmK98gOtCMjqgrztfb95HI6ircioht4kmtzXFTStJdVv7mahzTtEIvc8jpEPvfvGU ghkA== X-Forwarded-Encrypted: i=1; AJvYcCWV8GASXU3fejITthNBD7Ur8g6eHjAWkLUhwgIvYUmZFN80vDeaUC+x9XorFua82vvjpfKClogu2Dp9h9o=@vger.kernel.org X-Gm-Message-State: AOJu0YyWJgTlqm/0sWpFr8fL1kuVIYbqOZpRbJuc1Nfr6l5zwNZA9U2/ jiIKd/oVwDycrZS6+fvdBzlqrgE+tCtlNZzixC+DmV7y7FpYDn1UlpzBf3K8YkA= X-Gm-Gg: ASbGncsHDY67ZV1zw4OJmR+dwrI/x8QhMsjgVLO/oOn8fF6TNZtUstvAt+lZSaUT4ie tBoeEuRqxoz2gqKq6NQmrk3WNbd15Gnp11f9Jah0eB2484P0rlUZOStuHLcwgKypx9mx8AOyM8M ei7HUYcVhv4fKmnW0pzXy43Yk+gBkr4wwc/czYkwzpEKDkf7xt1Vi3p6r1Ey+J78EFu6I7wWWnL RKkN0xaMm/bSwzsjT5W2SUJ+HxuZAH80n5jUKnmsco4H3MMUkp/ X-Google-Smtp-Source: AGHT+IFV2jJmdKrtGXDNBn0faBCdSKKOm2jok/QDUilDkRPeSOsI7kb8yVZCyBno96tZfMHWgdo/dw== X-Received: by 2002:a05:6000:491a:b0:385:bc42:52e4 with SMTP id ffacd0b85a97d-385c6eba8bemr2618099f8f.24.1732714982786; Wed, 27 Nov 2024 05:43:02 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:02 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 3/9] coresight: config: API to dynamically load / unload config tables Date: Wed, 27 Nov 2024 13:42:50 +0000 Message-Id: <20241127134256.2254851-4-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add API functions and helpers to runtime / dynamically load and unload configuration tables. Provides locking to ensure simutaneous load / unload from different sources cannot occur. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-syscfg-configfs.c | 365 ++++++++++++++++++ .../hwtracing/coresight/coresight-syscfg.c | 103 ++++- .../hwtracing/coresight/coresight-syscfg.h | 19 +- 3 files changed, 480 insertions(+), 7 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/driv= ers/hwtracing/coresight/coresight-syscfg-configfs.c index 6e8c8db52d39..d0aaecb0f4c7 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -5,10 +5,369 @@ */ =20 #include +#include +#include =20 #include "coresight-config.h" +#include "coresight-config-table.h" #include "coresight-syscfg-configfs.h" =20 +/* prevent race in load / unload operations */ +static DEFINE_MUTEX(cfs_mutex); + +/* + * need to enable / disable dynamic table load when + * initialising / shutting down the subsystem, or + * loading / unloading configurations via module. + */ +static bool cscfg_dyn_load_enabled; + +/* + * Lockdep issues occur if deleting the config directory as part + * of the unload operation triggered by configfs. + * Therefore we schedule the main part of the unload to be completed as a = work item + * & save the owner info for the scheduled unload + */ +static struct cscfg_load_owner_info *cscfg_sched_dyn_unload_owner; + + +/* determine if load / unload ops are currently permitted. */ +inline bool cscfg_load_ops_permitted(void) +{ + return (cscfg_dyn_load_enabled && !cscfg_sched_dyn_unload_owner); +} + +/* do the main unload operations. Called with cfs_mutex held */ +static int cscfg_do_unload(struct cscfg_load_owner_info *unload_owner) +{ + int err =3D 0; + + if (!cscfg_dyn_load_enabled) { + pr_warn("cscfg: skipping unload completion\n"); + return -EINVAL; + } + + err =3D cscfg_unload_config_sets(unload_owner); + if (!err) + cscfg_free_dyn_load_owner_info(unload_owner); + else + pr_err("cscfg: dynamic configuration unload error\n"); + + return err; +} + +/* complete the unload operation as work item */ +static void cscfg_complete_unload(struct work_struct *work) +{ + mutex_lock(&cfs_mutex); + + if (cscfg_sched_dyn_unload_owner) + cscfg_do_unload(cscfg_sched_dyn_unload_owner); + cscfg_sched_dyn_unload_owner =3D NULL; + + mutex_unlock(&cfs_mutex); + kfree(work); +} + +static int cscfg_schedule_unload(void) +{ + struct work_struct *work; + + work =3D kzalloc(sizeof(struct work_struct), GFP_KERNEL); + if (!work) + return -ENOMEM; + + INIT_WORK(work, cscfg_complete_unload); + schedule_work(work); + return 0; +} + +/* create a string representing a loaded config based on owner info */ +static ssize_t cscfg_get_owner_info_str(struct cscfg_load_owner_info *owne= r_info, + char *buffer, ssize_t size) +{ + struct cscfg_table_load_descs *load_descs; + ssize_t size_used =3D 0; + int i; + static const char * const load_type[] =3D { + "Built in driver", + "Loadable module", + "Runtime Dynamic table load", + }; + + /* limited info for none dynamic loaded stuff */ + if (owner_info->type !=3D CSCFG_OWNER_DYNLOAD) { + size_used =3D scnprintf(buffer, size, + "load name: [Not Set]\nload type: %s\n", + load_type[owner_info->type]); + goto buffer_done; + } + + /* dynamic loaded type will have all the info */ + load_descs =3D (struct cscfg_table_load_descs *)owner_info->owner_handle; + + /* first is the load name and type - need for unload request */ + size_used =3D scnprintf(buffer, size, "load name: %s\nload type: %s\n", + load_descs->load_name, + load_type[owner_info->type]); + + /* list of configurations loaded by this owner element */ + size_used +=3D scnprintf(buffer + size_used, size - size_used, + "(configurations: "); + if (!(size_used < size)) + goto buffer_done; + + if (!load_descs->config_descs[0]) { + size_used +=3D scnprintf(buffer + size_used, size - size_used, + " None )\n"); + if (!(size_used < size)) + goto buffer_done; + } else { + i =3D 0; + while (load_descs->config_descs[i] && (size_used < size)) { + size_used +=3D scnprintf(buffer + size_used, + size - size_used, " %s", + load_descs->config_descs[i]->name); + i++; + } + size_used +=3D + scnprintf(buffer + size_used, size - size_used, " )\n"); + } + if (!(size_used < size)) + goto buffer_done; + + /* list of features loaded by this owner element */ + size_used +=3D scnprintf(buffer + size_used, size - size_used, "(features= : "); + if (!(size_used < size)) + goto buffer_done; + + if (!load_descs->feat_descs[0]) { + size_used +=3D + scnprintf(buffer + size_used, size - size_used, " None )\n"); + if (!(size_used < size)) + goto buffer_done; + } else { + i =3D 0; + while (load_descs->feat_descs[i] && (size_used < size)) { + size_used +=3D scnprintf(buffer + size_used, + size - size_used, " %s", + load_descs->feat_descs[i]->name); + i++; + } + size_used +=3D + scnprintf(buffer + size_used, size - size_used, " )\n"); + } + + /* done or buffer full */ +buffer_done: + return size_used; +} + +void cscfg_enable_dyn_load(void) +{ + mutex_lock(&cfs_mutex); + cscfg_dyn_load_enabled =3D true; + mutex_unlock(&cfs_mutex); +} + +/* disable dynamic load / unload if no current unload scheduled */ +bool cscfg_disable_dyn_load(void) +{ + mutex_lock(&cfs_mutex); + if (!cscfg_sched_dyn_unload_owner) + cscfg_dyn_load_enabled =3D false; + mutex_unlock(&cfs_mutex); + return !cscfg_dyn_load_enabled; +} + +void cscfg_at_exit_dyn_load(void) +{ + mutex_lock(&cfs_mutex); + cscfg_dyn_load_enabled =3D false; + cscfg_sched_dyn_unload_owner =3D NULL; + mutex_unlock(&cfs_mutex); +} + + +struct cscfg_load_owner_info *cscfg_create_dyn_load_owner_info(void) +{ + struct cscfg_table_load_descs *load_descs =3D 0; + struct cscfg_load_owner_info *owner_info =3D 0; + + load_descs =3D kzalloc(sizeof(struct cscfg_table_load_descs), GFP_KERNEL); + if (!load_descs) + return owner_info; + + owner_info =3D kzalloc(sizeof(struct cscfg_load_owner_info), GFP_KERNEL); + if (owner_info) { + owner_info->owner_handle =3D load_descs; + owner_info->type =3D CSCFG_OWNER_DYNLOAD; + } else + kfree(load_descs); + + return owner_info; +} + +/* free memory associated with a dynamically loaded configuration & descri= ptors */ +void cscfg_free_dyn_load_owner_info(struct cscfg_load_owner_info *owner_in= fo) +{ + struct cscfg_table_load_descs *load_descs =3D 0; + + if (!owner_info) + return; + + if (owner_info->type !=3D CSCFG_OWNER_DYNLOAD) + return; + + load_descs =3D (struct cscfg_table_load_descs *)(owner_info->owner_handle= ); + + if (load_descs) { + /* free the data allocated on table load, pointed to by load_descs */ + cscfg_table_free_load_descs(load_descs); + kfree(load_descs); + } + + kfree(owner_info); +} + +/* return load name if dynamic load owned element */ +const char *cscfg_get_dyn_load_name(struct cscfg_load_owner_info *owner_in= fo) +{ + const char *name =3D "unknown"; + struct cscfg_table_load_descs *load_descs; + + if (!owner_info) + return name; + + load_descs =3D (struct cscfg_table_load_descs *)(owner_info->owner_handle= ); + if (owner_info->type =3D=3D CSCFG_OWNER_DYNLOAD) + return load_descs->load_name; + + return name; +} + +/* + * Dynamic load and unload configuration table API + */ + +/* dynamically load a configuration and features from a config table + */ +int cscfg_dyn_load_cfg_table(const void *table, size_t table_size) +{ + struct cscfg_table_load_descs *load_descs =3D 0; + struct cscfg_load_owner_info *owner_info =3D 0; + int err =3D -EINVAL; + + /* ensure we cannot simultaneously load and unload */ + if (!mutex_trylock(&cfs_mutex)) { + err =3D -EBUSY; + goto exit_unlock; + } + + /* check configfs load / unload ops are permitted */ + if (!cscfg_load_ops_permitted()) { + err =3D -EBUSY; + goto exit_unlock; + } + + if (table_size > CSCFG_TABLE_MAXSIZE) { + pr_err("cscfg: Load error - Input file too large.\n"); + goto exit_unlock; + } + + /* create owner info as dyn load type with descriptor tables to be filled= */ + owner_info =3D cscfg_create_dyn_load_owner_info(); + if (owner_info) + load_descs =3D (struct cscfg_table_load_descs *)(owner_info->owner_handl= e); + else { + err =3D -ENOMEM; + goto exit_unlock; + } + + /* convert table into internal data structures */ + err =3D cscfg_table_read_buffer(table, table_size, load_descs); + if (err) { + pr_err("cscfg: Load error - Failed to read input buffer.\n"); + goto exit_memfree; + } + + err =3D cscfg_load_config_sets(load_descs->config_descs, load_descs->feat= _descs, owner_info); + if (err) { + pr_err("cscfg: Load error - Failed to load configuaration table.\n"); + goto exit_memfree; + } + + /* load success */ + goto exit_unlock; + +exit_memfree: + /* frees up owner_info and load_descs */ + cscfg_free_dyn_load_owner_info(owner_info); + +exit_unlock: + mutex_unlock(&cfs_mutex); + return err; +} +EXPORT_SYMBOL_GPL(cscfg_dyn_load_cfg_table); + +/* + * schedule the unload of the last dynamically loaded table. + * load / unload ordering is strictly enforced. + */ +int cscfg_sched_dyn_unload_cfg_table(void) +{ + struct cscfg_load_owner_info *owner_info =3D 0; + int err =3D -EINVAL; + + /* ensure we cannot simultaneously load and unload */ + if (!mutex_trylock(&cfs_mutex)) { + err =3D -EBUSY; + goto exit_unlock; + } + + /* check dyn load / unload ops are permitted & no ongoing unload */ + if (!cscfg_load_ops_permitted()) { + err =3D -EBUSY; + goto exit_unlock; + } + + /* find the last loaded owner info block */ + owner_info =3D cscfg_find_last_loaded_cfg_owner(); + if (!owner_info) { + pr_err("cscfg: Unload error: Failed to find any loaded configuration\n"); + goto exit_unlock; + } + + if (owner_info->type !=3D CSCFG_OWNER_DYNLOAD) { + pr_err("cscfg: Unload error: Last loaded configuration not dynamic loade= d item\n"); + goto exit_unlock; + } + + /* set cscfg state as starting an unload operation */ + err =3D cscfg_set_unload_start(); + if (err) { + pr_err("Config unload %s: failed to set unload start flag\n", + cscfg_get_dyn_load_name(owner_info)); + goto exit_unlock; + } + + /* + * actual unload is scheduled as a work item to avoid + * lockdep issues when triggered from configfs + */ + cscfg_sched_dyn_unload_owner =3D owner_info; + err =3D cscfg_schedule_unload(); + +exit_unlock: + mutex_unlock(&cfs_mutex); + return err; +} +EXPORT_SYMBOL_GPL(cscfg_sched_dyn_unload_cfg_table); + +/* + * configfs object and directory operations + */ + /* create a default ci_type. */ static inline struct config_item_type *cscfg_create_ci_type(void) { @@ -517,6 +876,12 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mg= r) if (!ci_type) return -ENOMEM; =20 + /* dyncamic load and unload initially disabled */ + cscfg_dyn_load_enabled =3D false; + + /* no current scheduled unload operation in progress */ + cscfg_sched_dyn_unload_owner =3D NULL; + subsys =3D &cscfg_mgr->cfgfs_subsys; config_item_set_name(&subsys->su_group.cg_item, CSCFG_FS_SUBSYS_NAME); subsys->su_group.cg_item.ci_type =3D ci_type; diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtra= cing/coresight/coresight-syscfg.c index 11138a9762b0..6379e29a3aa0 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -554,6 +554,23 @@ static int cscfg_fs_register_cfgs_feats(struct cscfg_c= onfig_desc **config_descs, return 0; } =20 +/* + * check owner info and if module owner, disable / enable + * configfs managed dynamic load ops to prevent parallel load attempts. + */ +static bool cscfg_check_disable_dyn_load(struct cscfg_load_owner_info *own= er_info) +{ + if (owner_info->type =3D=3D CSCFG_OWNER_MODULE) + return cscfg_disable_dyn_load(); + return true; +} + +static void cscfg_check_enable_dyn_load(struct cscfg_load_owner_info *owne= r_info) +{ + if (owner_info->type =3D=3D CSCFG_OWNER_MODULE) + cscfg_enable_dyn_load(); +} + /** * cscfg_load_config_sets - API function to load feature and config sets. * @@ -578,10 +595,14 @@ int cscfg_load_config_sets(struct cscfg_config_desc *= *config_descs, { int err =3D 0; =20 + /* if this load is by module owner, need to disable dynamic load/unload */ + if (!cscfg_check_disable_dyn_load(owner_info)) + return -EBUSY; + mutex_lock(&cscfg_mutex); if (cscfg_mgr->load_state !=3D CSCFG_NONE) { - mutex_unlock(&cscfg_mutex); - return -EBUSY; + err =3D -EBUSY; + goto exit_unlock; } cscfg_mgr->load_state =3D CSCFG_LOAD; =20 @@ -616,7 +637,7 @@ int cscfg_load_config_sets(struct cscfg_config_desc **c= onfig_descs, =20 /* mark any new configs as available for activation */ cscfg_set_configs_available(config_descs); - goto exit_unlock; + goto exit_clear_state; =20 err_clean_cfs: /* cleanup after error registering with configfs */ @@ -631,9 +652,13 @@ int cscfg_load_config_sets(struct cscfg_config_desc **= config_descs, err_clean_load: cscfg_unload_owned_cfgs_feats(owner_info); =20 -exit_unlock: +exit_clear_state: cscfg_mgr->load_state =3D CSCFG_NONE; + +exit_unlock: mutex_unlock(&cscfg_mutex); + + cscfg_check_enable_dyn_load(owner_info); return err; } EXPORT_SYMBOL_GPL(cscfg_load_config_sets); @@ -659,8 +684,13 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_i= nfo *owner_info) int err =3D 0; struct cscfg_load_owner_info *load_list_item =3D NULL; =20 + /* if this unload is by module owner, need to disable dynamic load/unload= */ + if (!cscfg_check_disable_dyn_load(owner_info)) + return -EBUSY; + mutex_lock(&cscfg_mutex); - if (cscfg_mgr->load_state !=3D CSCFG_NONE) { + if ((cscfg_mgr->load_state !=3D CSCFG_NONE) && + (cscfg_mgr->load_state !=3D CSCFG_UNLOAD_START)) { mutex_unlock(&cscfg_mutex); return -EBUSY; } @@ -705,10 +735,43 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_= info *owner_info) exit_unlock: cscfg_mgr->load_state =3D CSCFG_NONE; mutex_unlock(&cscfg_mutex); + + cscfg_check_enable_dyn_load(owner_info); return err; } EXPORT_SYMBOL_GPL(cscfg_unload_config_sets); =20 +int cscfg_set_unload_start(void) +{ + int ret =3D 0; + + mutex_lock(&cscfg_mutex); + if (cscfg_mgr->load_state !=3D CSCFG_NONE) + ret =3D -EBUSY; + else + cscfg_mgr->load_state =3D CSCFG_UNLOAD_START; + mutex_unlock(&cscfg_mutex); + + return ret; +} + +/* find the last loaded config owner info */ +struct cscfg_load_owner_info *cscfg_find_last_loaded_cfg_owner(void) +{ + struct cscfg_load_owner_info *owner_info =3D NULL; + + mutex_lock(&cscfg_mutex); + + if (!list_empty(&cscfg_mgr->load_order_list)) + owner_info =3D list_last_entry(&cscfg_mgr->load_order_list, + struct cscfg_load_owner_info, item); + + + mutex_unlock(&cscfg_mutex); + return owner_info; + +} + /* Handle coresight device registration and add configs and features to de= vices */ =20 /* iterate through config lists and load matching configs to device */ @@ -881,7 +944,7 @@ static int _cscfg_activate_config(unsigned long cfg_has= h) struct cscfg_config_desc *config_desc; int err =3D -EINVAL; =20 - if (cscfg_mgr->load_state =3D=3D CSCFG_UNLOAD) + if (cscfg_mgr->load_state >=3D CSCFG_UNLOAD) return -EBUSY; =20 list_for_each_entry(config_desc, &cscfg_mgr->config_desc_list, item) { @@ -1206,6 +1269,7 @@ static int cscfg_create_device(void) static void cscfg_unload_cfgs_on_exit(void) { struct cscfg_load_owner_info *owner_info =3D NULL; + bool free_dynload_owner =3D false; =20 /* * grab the mutex - even though we are exiting, some configfs files @@ -1240,6 +1304,23 @@ static void cscfg_unload_cfgs_on_exit(void) */ pr_err("cscfg: ERROR: prior module failed to unload configuration\n"); goto list_remove; + + case CSCFG_OWNER_DYNLOAD: + /* + * dynamically loaded items may still be present if the user did not + * unload them during the session. These have dynamically allocated + * descriptor tables (unlike the two types above that are statically + * allocated at compile time) + */ + pr_info("cscfg: unloading dynamically loaded configuration %s\n", + cscfg_get_dyn_load_name(owner_info)); + + /* + * as this is not being unloaded by configfs, need to flag the + * requirement to free up the owner info and descriptors. + */ + free_dynload_owner =3D true; + break; } =20 /* remove from configfs - outside the scope of the list mutex */ @@ -1253,6 +1334,12 @@ static void cscfg_unload_cfgs_on_exit(void) list_remove: /* remove from load order list */ list_del(&owner_info->item); + + /* dynamic loaded config, free memory now */ + if (free_dynload_owner) { + cscfg_free_dyn_load_owner_info(owner_info); + free_dynload_owner =3D false; + } } mutex_unlock(&cscfg_mutex); } @@ -1284,6 +1371,9 @@ int __init cscfg_init(void) if (err) goto exit_err; =20 + /* can now allow dynamic table load / unload */ + cscfg_enable_dyn_load(); + dev_info(cscfg_device(), "CoreSight Configuration manager initialised"); return 0; =20 @@ -1294,5 +1384,6 @@ int __init cscfg_init(void) =20 void cscfg_exit(void) { + cscfg_at_exit_dyn_load(); cscfg_clear_device(); } diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtra= cing/coresight/coresight-syscfg.h index 66e2db890d82..ba137b092992 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.h +++ b/drivers/hwtracing/coresight/coresight-syscfg.h @@ -20,7 +20,8 @@ enum cscfg_load_ops { CSCFG_NONE, CSCFG_LOAD, - CSCFG_UNLOAD + CSCFG_UNLOAD, + CSCFG_UNLOAD_START, /* unload started by fs, will be completed later */ }; =20 /** @@ -79,6 +80,7 @@ struct cscfg_registered_csdev { enum cscfg_load_owner_type { CSCFG_OWNER_PRELOAD, CSCFG_OWNER_MODULE, + CSCFG_OWNER_DYNLOAD, /* dynamic loading at runtime */ }; =20 /** @@ -108,6 +110,17 @@ int cscfg_update_feat_param_val(struct cscfg_feature_d= esc *feat_desc, int cscfg_config_sysfs_activate(struct cscfg_config_desc *cfg_desc, bool a= ctivate); void cscfg_config_sysfs_set_preset(int preset); =20 +struct cscfg_load_owner_info *cscfg_find_last_loaded_cfg_owner(void); +int cscfg_set_unload_start(void); + +void cscfg_enable_dyn_load(void); +bool cscfg_disable_dyn_load(void); +void cscfg_at_exit_dyn_load(void); + +struct cscfg_load_owner_info *cscfg_create_dyn_load_owner_info(void); +void cscfg_free_dyn_load_owner_info(struct cscfg_load_owner_info *owner_in= fo); +const char *cscfg_get_dyn_load_name(struct cscfg_load_owner_info *owner_in= fo); + /* syscfg manager external API */ int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs, struct cscfg_feature_desc **feat_descs, @@ -124,4 +137,8 @@ int cscfg_csdev_enable_active_config(struct coresight_d= evice *csdev, void cscfg_csdev_disable_active_config(struct coresight_device *csdev); void cscfg_config_sysfs_get_active_cfg(unsigned long *cfg_hash, int *prese= t); =20 +/* Dynamic load and unload configuration table API */ +int cscfg_dyn_load_cfg_table(const void *table, size_t table_size); +int cscfg_sched_dyn_unload_cfg_table(void); + #endif /* CORESIGHT_SYSCFG_H */ --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6869C1FCFCA for ; Wed, 27 Nov 2024 13:43:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714987; cv=none; b=iVhbhAB2HjUyAuKNzpKG/oDLxLGE9IYe4ktBPkLNXZV2JnnF6xEIh2rIpSEstTTpMcKPuPC/nTL+OSfKqAzKvHtcDFFkmy1a55XktxhV9YFizSyCorHmTioreLHljENNrudeNhtZyaNPNKC0+C8buJBwCkGvGGLoOcw5mMO/kLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714987; c=relaxed/simple; bh=Mk/4oOZJD/COA6vI8fctB4AcWiipnUaW6StudvCDXIA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dqbgG/EvnD6ku9fo4RvVAjOEuoSY6KUA+rdx7AN/8TrJBrwH2Um/QgEFqyjSSyHpemUn8opD+bFG8WmQpB1fqzALP59ciU0rJZ/QiW+FTZYwoWzTTHevclHYdTrzIbjIciR7ZjuounNVTzYHLBFg61yXpmQISqTRc/DshTKr58M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=eEwqmLKc; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="eEwqmLKc" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-3823f1ed492so478790f8f.1 for ; Wed, 27 Nov 2024 05:43:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714984; x=1733319784; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QDdX1bl5lCymW1Raij3h1SHKKmloqC4GtdPMjepmrjc=; b=eEwqmLKclcYO5B8TRLjbnrE/RBc9zbk2vdSgrQeTMZL2Chjyh3pk0FkDTBuN8lQ+7Y nPOykw7fjGxLgb1g007PiK+BJTevnPluxpQw9hbaHf76QU5sthtegJWZJxgejxKZzRkb UypFzU+N49S5D1RJjns4uDRzJdLcje0sxQ0cH7sp/5zVnDP51EttTjml+mf+ObrDMhJt SIIvQqzkPIUhc26LxN+cMCpS6e7HyEFYhIU+vweYlAK1ZveCd+KvK4EI1Ouhl9hNxW+A hN2xu37PPEbowiMUGV9grGe1NRU6aNbbZSihjx2nmt73+6E985rQoN3MObEyNPrTLRMQ HfHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714984; x=1733319784; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QDdX1bl5lCymW1Raij3h1SHKKmloqC4GtdPMjepmrjc=; b=NJqhvRVTbVOag99Tiv6UlUr/Oz73u4xbcWwiAXCzQvL1dwZo+738BBFC4vLVCpP+BA cp7JZRv1sM97Zj0G/5+mpt1rPfIm0DQ9wSBdbJ24afd5q6b7AtyU1rlqwqIeqmdxk5+Q F4+5tMp3FTxc/VYphmsmbjMmlJI9URzp1BrC90CGfSKhQ7xO0ZOuUDkm0dS4zE8Ff32e 82KoB1m0DbIOSLOeTWFaFDkTlVQenCOFViL/n2RZu5m/fkj15gfMCEiLAVDM7cCl58Sq NuEP60B2kjIBkhfrQlLBqIDXxBOa8AUMLA9/I5/ZG7JERXOZhL/Y5Idtf3pT5hEth14K m2CQ== X-Forwarded-Encrypted: i=1; AJvYcCW1f/n3PmybiZhDgxO77GfuY7XJv7tjD95/UeaE1aI1hV8UiZ1UvMmSgE+YMWChRhD+Yb2zQQPisyil/3U=@vger.kernel.org X-Gm-Message-State: AOJu0YwCB9UlP8jvs66G+gwBge4d08ZfmGZUQRHbOzhvOlm+styqfgfR ndyG+vLji1i3eLRs6PSR5yWfvWOR9NBvwrx1R1JgJtP3HER7yzn9JZyZSjFGJXE7q67xFX8MrpC 0 X-Gm-Gg: ASbGncugQ4ndth7UrAzcPADj5Sof0u/CYzQXDJJmkv8XYHqIaYfxal/S+hTbqr6HHyZ EKovf67uEi5rUpqmUdsBXgYbfKqUsqrE6S3iQjfr+0Xn/giQ0F4Fcux1nqiGtO7GA2V4ywlcO0/ YfV0qBhybBtgMwdEawt+DOihXf+OTd4Ikp3SFc83HLBHuA6RG1Peltt2VnixUuNLhUo0rO9cV/N mQlYViAJwrynO5KglSkLbZC1SOQmzTnvqej8xSVw7w0/6KX6CWh X-Google-Smtp-Source: AGHT+IHnIHtF2qzsUAy84w9INuHabsV2StfM6k9CccIqh4w5X+PX/yHdHb7SF224RLo5vdd62N/PQw== X-Received: by 2002:a05:6000:4008:b0:382:4abd:c3c9 with SMTP id ffacd0b85a97d-385c682052emr2879532f8f.7.1732714983771; Wed, 27 Nov 2024 05:43:03 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:03 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 4/9] coresight: configfs: Add static type for config attributes Date: Wed, 27 Nov 2024 13:42:51 +0000 Message-Id: <20241127134256.2254851-5-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add in a static attribute ci_type and remove dynamic generated ci_type in preparation for adding in new attributes. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-syscfg-configfs.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/driv= ers/hwtracing/coresight/coresight-syscfg-configfs.c index d0aaecb0f4c7..83da4820be6d 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -790,14 +790,20 @@ static void cscfg_destroy_feature_group(struct config= _group *feat_group) kfree(feat_view); } =20 -static struct config_item_type cscfg_configs_type =3D { + +static struct config_item_type cscfg_configs_load_type =3D { + .ct_owner =3D THIS_MODULE, +}; + +/* configurations group */ +static struct config_item_type cscfg_configs_grp_type =3D { .ct_owner =3D THIS_MODULE, }; =20 static struct config_group cscfg_configs_grp =3D { .cg_item =3D { .ci_namebuf =3D "configurations", - .ci_type =3D &cscfg_configs_type, + .ci_type =3D &cscfg_configs_grp_type, }, }; =20 @@ -867,15 +873,10 @@ void cscfg_configfs_del_feature(struct cscfg_feature_= desc *feat_desc) int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr) { struct configfs_subsystem *subsys; - struct config_item_type *ci_type; =20 if (!cscfg_mgr) return -EINVAL; =20 - ci_type =3D cscfg_create_ci_type(); - if (!ci_type) - return -ENOMEM; - /* dyncamic load and unload initially disabled */ cscfg_dyn_load_enabled =3D false; =20 @@ -884,7 +885,7 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr) =20 subsys =3D &cscfg_mgr->cfgfs_subsys; config_item_set_name(&subsys->su_group.cg_item, CSCFG_FS_SUBSYS_NAME); - subsys->su_group.cg_item.ci_type =3D ci_type; + subsys->su_group.cg_item.ci_type =3D &cscfg_configs_load_type; =20 config_group_init(&subsys->su_group); mutex_init(&subsys->su_mutex); --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E0E21FCF69 for ; Wed, 27 Nov 2024 13:43:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714988; cv=none; b=HfGGmw3lOOQM40BsufcsGUxCWwL9a+270cxHQpXIvIbvFTYkRFzvj1Pj7HJ8WNBCqXIHAL2p0oQfxHgAsCL+/tGWTbUcxrGVLx+HZlSs7TEWGsAgCtA8AfiWiyKSfYHS11XNUgP418+3CHIktdmBPhPjz9rl6x6iOUXPT4JMQqk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714988; c=relaxed/simple; bh=K7n0wxVY/ilMwwjUvSqV57HP9mOotkMw60khUxl2FW4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cLqw6Q+qPpkXkhABSJtkb6lGzZx/2OK7/Ap/5hDqyOSdSe8Ur52A1LGY/skCkVxzZ38jwrSm+/F4GrJvdmVz1JbKf63QIKTcuUgFy9RbUyL2UTOp7Yu7MnL8HIkj/tcciOrWlPtvE5lliOg/xGoKa31BOtp9fD6PI5zXJ4UT6L8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=GrrgMVxs; arc=none smtp.client-ip=209.85.221.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="GrrgMVxs" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-3823eaad37aso546817f8f.0 for ; Wed, 27 Nov 2024 05:43:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714985; x=1733319785; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uwYuMbr1LfJ5VAFpw4rhCtYlWSRl0WXyDX33mfRehWo=; b=GrrgMVxsbhgYbsGLK5zns5rWKjI1+0rcbSkiUV5unm1u/RtVLHE/BIJypw6wEREoqY VRbpStWc/uvfcpiKDZQHuPu///kYS/LrKs1dhGgi+01jAOELkghUbimtfviqI1Uq+QnK AALjsQ1davO3sqceYtoHZsGPTdns88k+kSdKskUs6fIhNJAkhrEC+4yRWePmTJ0oSihR x/Owz9hLZjPSv26DNDACiqlAQUrPXnY+dAKY8+VP5Lpj3qfs5sfA6CrxJf46ncWjMCId Pf+wPE9NME2fxyp1HrXZ2C/XpDhaN45O1OkAQ10TppEjjqrc+EFcpQVtzzNnq+SEhzUU 7KjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714985; x=1733319785; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uwYuMbr1LfJ5VAFpw4rhCtYlWSRl0WXyDX33mfRehWo=; b=DBMuU7uEonEFKwL4N5WthZ+LQU2SUfi4Iry5MSuq7ZShii77jGBl2swa0kksbvZC46 cOrQxqKl0X4lV+uUwIZHiN3kWdnpv3zFfvRphgQGTN8YZ9FnTD1WTuXTGdsegXQDNTsn XpPXJw3Nf87LeU77/hFn1jhsHAuddXANtUdlSiDWhM/k3XMMB6JdSpfaTjyuUnb1fYPa 2RTIL9owPMSqya00sYwlWCzTPjeT6hTWVTOu+FWc/PV30Puv9qh1+6vZkSeAQlF1KPDu QhevlPRvzrQ0QQFEiYk+JJKls12KNa98vlP/YkU5JoaJq1MB8Go0KJETSNaAru+8yvhe fTsQ== X-Forwarded-Encrypted: i=1; AJvYcCWrJ5I0z1wyotVSzWr2XzzubuVKBL2yj2/7D0lLK9+AS+uoQ+cSLqyb6BAG9pgwPNnbJnhXQ8Gz+pzGQfU=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9XTaatKf9/I1pczSCq74/MLrcwvkLlTq5MYYtd+apRA51gMcp Ub7APAXEcHkIWdpstzZWa+sw29RVciFwDGGspj1PYh5rHGYXGUbcTalfiWIKfcU= X-Gm-Gg: ASbGncsGVYyHHkZO5Chxfl2M38T76G+YxkaNXEaGUQCVxmkmtoioxEFpikcJAegsZd7 MBBiu1VOVunuUSohHhsy1lM6o+3ugbqCHfoqqzBSAj9YJS1cQCsgVXuh6QUj5dnva159bSjaAlP /R5bkQqkLuTjZvE6zF5VyF6w9ode7JXAXfviaU7/V+5s6Mz0SbNXrHkovZnJCkZdJjSoV9sJK+R GBhMZcnCHjvgBWxqCUmtVDhQkvSrBnfjN+AXwOXfD9rMOXxMbey X-Google-Smtp-Source: AGHT+IHV4zsXiet1ZrBKIrnL9MpU+lNAH9wdVPgHqqFcCo9pkcAoRtI2rRGLhjawXq7Am076lKeAkA== X-Received: by 2002:a05:6000:156f:b0:382:4a94:af0a with SMTP id ffacd0b85a97d-385c684154fmr2111461f8f.20.1732714984760; Wed, 27 Nov 2024 05:43:04 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:04 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 5/9] coresight: configfs: Add attributes for unload operations Date: Wed, 27 Nov 2024 13:42:52 +0000 Message-Id: <20241127134256.2254851-6-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add attributes to view last loaded configuration, and to unload last loaded configuration, if it was loaded as a dynamic config table. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-syscfg-configfs.c | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/driv= ers/hwtracing/coresight/coresight-syscfg-configfs.c index 83da4820be6d..d7883fe802b5 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -790,9 +790,71 @@ static void cscfg_destroy_feature_group(struct config_= group *feat_group) kfree(feat_view); } =20 +/* Attributes in configfs that allow load and unload of configuration tabl= es */ + +static ssize_t +cscfg_cfg_unload_last_table_store(struct config_item *item, const char *pa= ge, size_t count) +{ + int err; + unsigned long val; + + err =3D kstrtoul(page, 0, &val); + if (err) + return err; + + if (val > 0) { + /* schedule unload of last dynamic loaded configuration */ + err =3D cscfg_sched_dyn_unload_cfg_table(); + if (!err) + err =3D count; + } else + err =3D -EINVAL; + + return err; +} +CONFIGFS_ATTR_WO(cscfg_cfg_, unload_last_table); + +static ssize_t cscfg_cfg_show_last_load_show(struct config_item *item, cha= r *page) +{ + struct cscfg_load_owner_info *owner_info =3D 0; + ssize_t size =3D 0; + + /* ensure we cannot read last load while loading / unloading */ + if (!mutex_trylock(&cfs_mutex)) + return -EBUSY; + + /* check dyn load / unload ops are permitted & no ongoing unload */ + if (!cscfg_load_ops_permitted()) { + size =3D -EBUSY; + goto exit_unlock; + } + + /* find the last loaded owner info block */ + owner_info =3D cscfg_find_last_loaded_cfg_owner(); + if (!owner_info) { + size =3D scnprintf(page, PAGE_SIZE, + "Failed to find any loaded configuration\n"); + goto exit_unlock; + } + + /* get string desc of last unload configuration from owner info */ + size =3D cscfg_get_owner_info_str(owner_info, page, PAGE_SIZE); + +exit_unlock: + mutex_unlock(&cfs_mutex); + return size; +} +CONFIGFS_ATTR_RO(cscfg_cfg_, show_last_load); + +static struct configfs_attribute *cscfg_config_configfs_attrs[] =3D { + &cscfg_cfg_attr_unload_last_table, + &cscfg_cfg_attr_show_last_load, + NULL, +}; =20 static struct config_item_type cscfg_configs_load_type =3D { .ct_owner =3D THIS_MODULE, + .ct_attrs =3D cscfg_config_configfs_attrs, }; =20 /* configurations group */ --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 826401FCFE9 for ; Wed, 27 Nov 2024 13:43:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714989; cv=none; b=vD6utYXfnbbCl3oSWuCbeyRxnKu8BgkBoultTEBp3UCeqnQ74Qd5gzp3jmUNO8/WPOHiB1uPj1S9P1kYDHp+c2KvcwoXtiPtZiBZ6byTGVEgNAs/RMhPUavUkmlXYrgK6za4DW2w9a2sA5XGQtsmFGQDniXKfrHfoynwbwMxhHg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714989; c=relaxed/simple; bh=uR+2gUFaQ/bKOjmUqL7EE/x3pFNAGPUlCiSBh+z2VYc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=m8JdRhA6vpD6bZXLSYgnaLLoRnDI2Am/moJVq0cU9Z6m7S4FUaQziZTuP3t/UtG5VQ/dQUzPsgg8eipHzMUw1g7rdT39vRTXKxwcLv8LoZfSZn5tWvj/w0O0hYnqXsDJSUwShK9urSuneyhRWayLBY8SqU5TYyLykj3ZVeLwK9w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=UlUcSyKy; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="UlUcSyKy" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-434a099ba95so27263745e9.0 for ; Wed, 27 Nov 2024 05:43:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714986; x=1733319786; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1NiDU4+PesaIdwCfPunSw0bMrPrm9AGZnmPORKEPq5c=; b=UlUcSyKyhltzeRqSKX0nv8rGgoqvCQKMYL/I+bwq4TnFvxFpQ7ZNm4z27vi8mhabHj 4vuCD7ZM2+ohCJh91RDzcklizYgMtWXANg8aHuMrvwKZX9QWArVJ6Zr45mGmcJKVwZ0u GQr7Y9jheDCwEbpUHipX5IdfrvyuTHxjnOKeo43YD/zu/h9slz3nUA314YlLqYNB5x4w C2/RhVah1rJEKlqpwJNQE6mBCQ+Wak0b6bl8Xl681q+10zsvch8cXVo472ATEG4uV24f 6Khya+8ouTV432xXzrijNJgjoPirK4NXCDnbc3w3fKimldMWdE6wLUGNQBOW46qLqslG 7pwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714986; x=1733319786; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1NiDU4+PesaIdwCfPunSw0bMrPrm9AGZnmPORKEPq5c=; b=Eov1L7B6+zKnMznmxznt68ME8oN5oBmqlhff0WXRu+chkblF/HV4XAdUYRnrgE8JxQ v3ZJCDnuAYHPzQRNAQZA5tEORekHnxguvp+jOhWMVFTgeb6s9CB1FQC3YzSqEREYIemu oYlNc/Eif2/yCwqBivv/qR31S96KLTU81Tsf+ar0VBQmq0lkXr/1goljhRrdQegtTmni apyOd7YKForlEjfrkNNV2Sva0Hu9+XvMxTAOFSoO7fDNn8gamp3xGec03dDzujH50dtN EFf8e5mbM7d/+2135AJau4YJgDoTorEwqN1cZD+BbEc+mlE9dQkZtIb+8YCAbxr7DkGp yT3g== X-Forwarded-Encrypted: i=1; AJvYcCWFiVCqDAQ6Gp8NdwdCBypjACBCPjKzb3RgpDzVAGuCsMy7nCkjf9T55162DH9mee1VQwgiQaKuCTXl9N4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw+Eum6GrbLjlX58lGolq+sDrL2BxzF6SE2L7JU2cwvqTqAZ5eB pqsLXB58iw792Qy0E1I2KhH3ddkNmEaUoCWsytzTwf1VESpTzYGe9Qvz8cEvV2s= X-Gm-Gg: ASbGnctKK99fngWGfc2uV8AEGWhmpjZWvAtLS56ayqxqhoxWxAH7V6CJ5D43fcHVJVt Nx1C6tQ6t5KuCoADtOPep5TR/UXG5HbMWoARc2jrpJhJ4v5KKMOxBpF6fniEwWXWY1R4p2DMfGO FXpFjZ2Ms+i5LUVvtfZIj3ppeE8QHjacj+2CKS/iI/E3vr5SSdTM6mI5YnOWxTs5VLzDssUg18/ LxAebA0Ujz/1ykur81UMttmTK4vV1q8nU9xqW1RMEq8rUohtIY/ X-Google-Smtp-Source: AGHT+IE989jzkeAsumQF9Xor81wjfIshk1Fi9eocD3+gjibZ7MizC96YWhPR+VcT19M8dHkWDMMcxA== X-Received: by 2002:a05:600c:350c:b0:434:a781:f5e2 with SMTP id 5b1f17b1804b1-434a9dc0c94mr29355435e9.8.1732714985815; Wed, 27 Nov 2024 05:43:05 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:05 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 6/9] coresight: configfs: Add attribute to load a configuration table Date: Wed, 27 Nov 2024 13:42:53 +0000 Message-Id: <20241127134256.2254851-7-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add in a binary attribute to allow load of a configuration table. Calls API function to load and validate incoming table. Use of binary attribute in this way is modelled on the load of ACPI tables which also use a binary configfs attribute. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-syscfg-configfs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/driv= ers/hwtracing/coresight/coresight-syscfg-configfs.c index d7883fe802b5..ce8eabc86701 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c @@ -791,6 +791,16 @@ static void cscfg_destroy_feature_group(struct config_= group *feat_group) } =20 /* Attributes in configfs that allow load and unload of configuration tabl= es */ +static ssize_t cscfg_cfg_load_table_write(struct config_item *item, const = void *buffer, size_t size) +{ + int err =3D 0; + + err =3D cscfg_dyn_load_cfg_table(buffer, size); + if (err) + return err; + return size; +} +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, load_table, NULL, CSCFG_TABLE_MAXSIZE); =20 static ssize_t cscfg_cfg_unload_last_table_store(struct config_item *item, const char *pa= ge, size_t count) @@ -846,6 +856,11 @@ static ssize_t cscfg_cfg_show_last_load_show(struct co= nfig_item *item, char *pag } CONFIGFS_ATTR_RO(cscfg_cfg_, show_last_load); =20 +static struct configfs_bin_attribute *cscfg_config_configfs_bin_attrs[] = =3D { + &cscfg_cfg_attr_load_table, + NULL, +}; + static struct configfs_attribute *cscfg_config_configfs_attrs[] =3D { &cscfg_cfg_attr_unload_last_table, &cscfg_cfg_attr_show_last_load, @@ -855,6 +870,7 @@ static struct configfs_attribute *cscfg_config_configfs= _attrs[] =3D { static struct config_item_type cscfg_configs_load_type =3D { .ct_owner =3D THIS_MODULE, .ct_attrs =3D cscfg_config_configfs_attrs, + .ct_bin_attrs =3D cscfg_config_configfs_bin_attrs, }; =20 /* configurations group */ --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C700D1FDE06 for ; Wed, 27 Nov 2024 13:43:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714991; cv=none; b=DSK1B3xAqHF5yuFh5o6e8xvXFkMc8u39sx0xgEVxqfP5c3K7FOciWcLcZnu08Q8eM4Q4snwChGAuHdhRcld32hFWb0b5K8qDb8siTOmM9oggbFylcO0r+watzPe6cnMrVaAXzYS0pwQXgAdNRHuVN1ApzhPeryfsqq36OHd7Ppk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714991; c=relaxed/simple; bh=6SmMJAf9CZoPM2pBGfCIuxo2qHcNIdQ3HyAIr7NA57A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ql7zWsal1jGhLbVUkzQ7e8fXFR+BmR2ru78jeQa6vUcat3ERMgMeBuzNoJ8FroX6RXO/gKZeQ0X+Vd4TSoBSbDZREZe729SGBqX6tEW0iRzbpRNHhToo0Z/dHOim5VYvDTZAaIUDTcs1Y9KlyFQxu7DZi1Tf83WHjTRNwZ/7Fls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=Cct4TISr; arc=none smtp.client-ip=209.85.221.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Cct4TISr" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-3824446d2bcso6039541f8f.2 for ; Wed, 27 Nov 2024 05:43:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714987; x=1733319787; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Z7kJgHNm01IKskzLmLKRceDBFi0cAMzANbqkhR3ncBI=; b=Cct4TISrhAamkVTSWuR1tNOHxz7yCKkkssFrCN9BCkiFLjLtZ25E4eYktRrw+cnesf eca/6V+xLvh1kWEmwlM3XhaD2wT6+7OTK5zN7/MRq51pInUdm23JR3K2OSjl5h3xU/Kt llir7lgu5ui353fJv06XXz6XF5PoeyJh315pakRjENf8KMAZl97H+w3tQaeoTtaw41hY KM/zyvNykBrLV63OIZh8C/jHtzZiEv8e40vkQlBx3Y29v1SWc+u050j4Q6MmwrIxdBBC KvxisqXFd9YqsGhsH9iVzaB+xXxSoSLo6Pj9UVhF+3hWM5M4tJnS/W4stIDTzySDWfYc EdDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714987; x=1733319787; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Z7kJgHNm01IKskzLmLKRceDBFi0cAMzANbqkhR3ncBI=; b=Uz8YsxuZhzq4CP7uN3Hzm6SoYK8Tdbksvzzn2g/mw12k4jWOiSdF92vRJnNIFgRzdE eBRU4vOL2A7jwEWEqyfO6JBcTKWZ4addFwh/530wz8fKEFQU/zcHvuJwY3nLWPpud0Cu j7UmizQjeCvQaHyUM/Ln92L/Y1kswdr4aHW6XrKDgqa+0QxVCJCP5CCTLs6R2SAthASg qcZfJ1/AE3RpRKLn/smZAByuxEqkI7qByRz0UK5K1AwNXS8oU7Pzae8cfSfYW2kOIMVu rFa//9eQdKmRqLZMTWE9LqqG3lyMegcV1SWymJzsMnm8VXHMAJxFLkUHUxzVhitKOhVq BIaA== X-Forwarded-Encrypted: i=1; AJvYcCXBl4DeZDOGkiHIvAcQSeWxxdohQPPkh4oO3euTfxTreumorJ9j9mgpeCRElrrr7CvYVUy1BjexiRO+RAs=@vger.kernel.org X-Gm-Message-State: AOJu0Yyl4SwliYW/P41V4Q8DM1p6coFgyzHNa1VKk4Z5SkUc8wFkUMu4 EJ4poELw4aOtJjtRcGMlPpH6iIsK42TCtDykZ9AH3rH4cgb7lyIe+q7k3tTCkLI= X-Gm-Gg: ASbGncuzWZpsDdfmjM79+1r8Gr+BzDGgpqXZtdvKMg6qbie+VnNsbmRKKkf8j6Z0S/+ MhXwyAdwJSIa4ckRFl8zBZ13otJdOuW6C7nGNyZtdveHuiaAe6Ukwl1s6bjZtMCEzyNH3Inco+C mhJAPZlBgb9UfMDfyGEA78hVzE8ciGKpbe2gwndhLzSZrsjUB2vjRy6y2ZjuPakvxghMytenaYb VbkdCpJ+r0dkGsWyYsQn7AdpgxJ4/jbyX6cgq4zW6DkHrUtZJcQ X-Google-Smtp-Source: AGHT+IHEffJbV5FU44Sg2vjvGFPHX08rvjIkS/DbTK9x0xFkC61oO4Ei4XnSE2bObrNaR7appe2FPw== X-Received: by 2002:a05:6000:156f:b0:382:495c:dee5 with SMTP id ffacd0b85a97d-385c6ed9398mr2565246f8f.37.1732714986968; Wed, 27 Nov 2024 05:43:06 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:06 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 7/9] coresight: config: extract shared structures to common header file Date: Wed, 27 Nov 2024 13:42:54 +0000 Message-Id: <20241127134256.2254851-8-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extract shared user space and kernel common structures from coresight-config.h into common header file coresight-config-desc.h Abstract memory allocation in coresight-config-table.c to allow read table functions to be run in userspace and kernel drivers. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../coresight/coresight-config-desc.h | 105 ++++++++++++++++ .../coresight/coresight-config-table.c | 66 +++++----- .../hwtracing/coresight/coresight-config.h | 119 ++++-------------- 3 files changed, 165 insertions(+), 125 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-config-desc.h diff --git a/drivers/hwtracing/coresight/coresight-config-desc.h b/drivers/= hwtracing/coresight/coresight-config-desc.h new file mode 100644 index 000000000000..4a487743d7e2 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-config-desc.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_DESC_H +#define _CORESIGHT_CORESIGHT_CONFIG_DESC_H + +/* Coresight Descriptors common to kernel and userspace applications */ +/* + * Register type flags for register value descriptor: + * describe how the value is interpreted, and handled. + */ +#define CS_CFG_REG_TYPE_STD 0x80 /* reg is standard reg */ +#define CS_CFG_REG_TYPE_RESOURCE 0x40 /* reg is a resource */ +#define CS_CFG_REG_TYPE_VAL_PARAM 0x08 /* reg value uses param */ +#define CS_CFG_REG_TYPE_VAL_MASK 0x04 /* reg value bit masked */ +#define CS_CFG_REG_TYPE_VAL_64BIT 0x02 /* reg value 64 bit */ +#define CS_CFG_REG_TYPE_VAL_SAVE 0x01 /* reg value save on disable */ + +/* + * flags defining what device class a feature will match to when processin= g a + * system configuration - used by config data and devices. + */ +#define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ +#define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ + +/* flags defining device instance matching - used in config match desc dat= a. */ +#define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ + +/* + * Limit number of presets in a configuration + * This is related to the number of bits (4) we use to select the preset on + * the perf command line. Preset 0 is always none selected. + * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c + */ +#define CS_CFG_CONFIG_PRESET_MAX 15 + +/** + * Parameter descriptor for a device feature. + * + * @name: Name of parameter. + * @value: Initial or default value. + */ +struct cscfg_parameter_desc { + const char *name; + u64 value; +}; + +/** + * Representation of register value and a descriptor of register usage. + * + * Used as a descriptor in the feature descriptors. + * Used as a value in when in a feature loading into a csdev. + * + * Supports full 64 bit register value, or 32 bit value with optional mask + * value. + * + * @type: define register usage and interpretation. + * @offset: the address offset for register in the hardware device (per de= vice specification). + * @hw_info: optional hardware device type specific information. (ETM / CT= I specific etc) + * @val64: 64 bit value. + * @val32: 32 bit value. + * @mask32: 32 bit mask when using 32 bit value to access device register = - if mask type. + * @param_idx: parameter index value into parameter array if param type. + */ +struct cscfg_regval_desc { + struct { + u32 type:8; + u32 offset:12; + u32 hw_info:12; + }; + union { + u64 val64; + struct { + u32 val32; + u32 mask32; + }; + u32 param_idx; + }; +}; + +/** + * Dynamically loaded descriptor arrays. + * + * For builtin or module loaded configurations / features these are + * statically defined at compile time. + + * For a dynamic load at runtime, using a config table, (e.g. load from + * configfs) we create the arrays dynamically so need a structure to + * manage these. + * + * @config_descs: array of config descriptor pointers. + * @feat_descs: array of feature descriptor pointers. + * @load_name: user readable name which may be used to unload later. + * Will be name of first config if present, or first feature. + */ +struct cscfg_table_load_descs { + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; + char *load_name; +}; + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_DESC_H */ diff --git a/drivers/hwtracing/coresight/coresight-config-table.c b/drivers= /hwtracing/coresight/coresight-config-table.c index 0a8f017d76d2..6216dffc9f9e 100644 --- a/drivers/hwtracing/coresight/coresight-config-table.c +++ b/drivers/hwtracing/coresight/coresight-config-table.c @@ -79,6 +79,7 @@ static int cscfg_table_read_elem_str(const u8 *buffer, co= nst int buflen, int *bu struct cscfg_table_elem_str *elem_str) { int used =3D *buf_used; + const u8 *str; =20 if ((buflen - used) < sizeof(u16)) return -EINVAL; @@ -88,11 +89,13 @@ static int cscfg_table_read_elem_str(const u8 *buffer, = const int buflen, int *bu if ((buflen - used) < elem_str->str_len) return -EINVAL; =20 + str =3D buffer + used; + /* check for 0 termination */ - if (buffer[used + (elem_str->str_len - 1)] !=3D 0) + if (str[elem_str->str_len - 1] !=3D 0) return -EINVAL; =20 - elem_str->str =3D kstrdup((char *)(buffer + used), GFP_KERNEL); + elem_str->str =3D cscfg_strdup((char *)str); used +=3D elem_str->str_len; =20 *buf_used =3D used; @@ -103,12 +106,13 @@ static int cscfg_table_alloc_desc_arrays(struct cscfg= _table_load_descs *desc_arr int nr_features, int nr_configs) { /* arrays are 0 terminated - nr_configs & nr_features elements */ - desc_arrays->config_descs =3D kcalloc(nr_configs + 1, sizeof(struct cscf= g_config_desc *), - GFP_KERNEL); + desc_arrays->config_descs =3D cscfg_calloc(nr_configs + 1, + sizeof(struct cscfg_config_desc *)); if (!desc_arrays->config_descs) return -ENOMEM; - desc_arrays->feat_descs =3D kcalloc(nr_features + 1, sizeof(struct cscfg_= feature_desc *), - GFP_KERNEL); + + desc_arrays->feat_descs =3D cscfg_calloc(nr_features + 1, + sizeof(struct cscfg_feature_desc *)); if (!desc_arrays->feat_descs) return -ENOMEM; return 0; @@ -123,24 +127,24 @@ static void cscfg_table_free_config_desc(struct cscfg= _config_desc *config_desc) return; =20 /* free presets */ - kfree(config_desc->presets); + cscfg_free((void *)config_desc->presets); =20 /* free feat ref strings */ if (config_desc->nr_feat_refs) { /* each string */ for (i =3D 0; i < config_desc->nr_feat_refs; i++) - kfree(config_desc->feat_ref_names[i]); + cscfg_free((void *)config_desc->feat_ref_names[i]); =20 /* and the char * array */ - kfree(config_desc->feat_ref_names); + cscfg_free((void *)config_desc->feat_ref_names); } =20 /* next the strings */ - kfree(config_desc->name); - kfree(config_desc->description); + cscfg_free((void *)config_desc->name); + cscfg_free((void *)config_desc->description); =20 /* finally the struct itself */ - kfree(config_desc); + cscfg_free((void *)config_desc); } =20 static int cscfg_table_read_elem_config(const u8 *buffer, const int buflen= , int *buf_used, @@ -165,7 +169,7 @@ static int cscfg_table_read_elem_config(const u8 *buffe= r, const int buflen, int return 0; =20 /* we have a config - allocate the descriptor */ - config_desc =3D kzalloc(sizeof(struct cscfg_config_desc), GFP_KERNEL); + config_desc =3D cscfg_zalloc(sizeof(struct cscfg_config_desc)); if (!config_desc) return -ENOMEM; =20 @@ -177,7 +181,7 @@ static int cscfg_table_read_elem_config(const u8 *buffe= r, const int buflen, int =20 /* allocate load name if not set */ if (!desc_arrays->load_name) - desc_arrays->load_name =3D kstrdup(config_desc->name, GFP_KERNEL); + desc_arrays->load_name =3D cscfg_strdup(config_desc->name); =20 /* read the description string */ err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); @@ -195,7 +199,7 @@ static int cscfg_table_read_elem_config(const u8 *buffe= r, const int buflen, int /* read the array of 64bit presets if present */ nr_preset_vals =3D config_desc->nr_total_params * config_desc->nr_presets; if (nr_preset_vals) { - presets =3D kcalloc(nr_preset_vals, sizeof(u64), GFP_KERNEL); + presets =3D cscfg_calloc(nr_preset_vals, sizeof(u64)); if (!presets) return -ENOMEM; =20 @@ -210,8 +214,8 @@ static int cscfg_table_read_elem_config(const u8 *buffe= r, const int buflen, int =20 /* read the array of feature names referenced by the config */ if (config_desc->nr_feat_refs) { - config_desc->feat_ref_names =3D kcalloc(config_desc->nr_feat_refs, - sizeof(char *), GFP_KERNEL); + config_desc->feat_ref_names =3D cscfg_calloc(config_desc->nr_feat_refs, + sizeof(char *)); if (!config_desc->feat_ref_names) return -ENOMEM; =20 @@ -255,17 +259,17 @@ static void cscfg_table_free_feat_desc(struct cscfg_f= eature_desc *feat_desc) return; =20 /* free up the register descriptor array */ - kfree(feat_desc->regs_desc); + cscfg_free((void *)feat_desc->regs_desc); =20 /* free up the parameters array */ - kfree(feat_desc->params_desc); + cscfg_free((void *)feat_desc->params_desc); =20 /* name and description strings */ - kfree(feat_desc->name); - kfree(feat_desc->description); + cscfg_free((void *)feat_desc->name); + cscfg_free((void *)feat_desc->description); =20 /* finally the struct itself */ - kfree(feat_desc); + cscfg_free((void *)feat_desc); } =20 static int cscfg_table_read_elem_feature(const u8 *buffer, const int bufle= n, int *buf_used, @@ -280,7 +284,7 @@ static int cscfg_table_read_elem_feature(const u8 *buff= er, const int buflen, int u32 val32; =20 /* allocate the feature descriptor object */ - feat_desc =3D kzalloc(sizeof(struct cscfg_feature_desc), GFP_KERNEL); + feat_desc =3D cscfg_zalloc(sizeof(struct cscfg_feature_desc)); if (!feat_desc) return -ENOMEM; =20 @@ -300,7 +304,7 @@ static int cscfg_table_read_elem_feature(const u8 *buff= er, const int buflen, int =20 /* allocate load name if not set previously by config */ if (!desc_arrays->load_name) - desc_arrays->load_name =3D kstrdup(feat_desc->name, GFP_KERNEL); + desc_arrays->load_name =3D cscfg_strdup(feat_desc->name); =20 /* read the description string */ err =3D cscfg_table_read_elem_str(buffer, buflen, &used, &elem_str); @@ -323,8 +327,8 @@ static int cscfg_table_read_elem_feature(const u8 *buff= er, const int buflen, int nr_regs_bytes =3D ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs); if ((buflen - used) < nr_regs_bytes) return -EINVAL; - feat_desc->regs_desc =3D kcalloc(feat_desc->nr_regs, - sizeof(struct cscfg_regval_desc), GFP_KERNEL); + feat_desc->regs_desc =3D cscfg_calloc(feat_desc->nr_regs, + sizeof(struct cscfg_regval_desc)); if (!feat_desc->regs_desc) return -ENOMEM; =20 @@ -338,8 +342,8 @@ static int cscfg_table_read_elem_feature(const u8 *buff= er, const int buflen, int =20 /* parameter descriptors - string + 64 bit value */ if (feat_desc->nr_params) { - feat_desc->params_desc =3D kcalloc(feat_desc->nr_params, - sizeof(struct cscfg_parameter_desc), GFP_KERNEL); + feat_desc->params_desc =3D cscfg_calloc(feat_desc->nr_params, + sizeof(struct cscfg_parameter_desc)); if (!feat_desc->params_desc) return -ENOMEM; for (i =3D 0; i < feat_desc->nr_params; i++) { @@ -421,7 +425,7 @@ void cscfg_table_free_load_descs(struct cscfg_table_loa= d_descs *desc_arrays) } =20 /* finally free up the load descs pointer arrays */ - kfree(desc_arrays->config_descs); - kfree(desc_arrays->feat_descs); - kfree(desc_arrays->load_name); + cscfg_free(desc_arrays->config_descs); + cscfg_free(desc_arrays->feat_descs); + cscfg_free(desc_arrays->load_name); } diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtra= cing/coresight/coresight-config.h index ea3aaf0d129b..8b298e9a3776 100644 --- a/drivers/hwtracing/coresight/coresight-config.h +++ b/drivers/hwtracing/coresight/coresight-config.h @@ -10,101 +10,10 @@ #include #include =20 -/* CoreSight Configuration Management - component and system wide configur= ation */ - -/* - * Register type flags for register value descriptor: - * describe how the value is interpreted, and handled. - */ -#define CS_CFG_REG_TYPE_STD 0x80 /* reg is standard reg */ -#define CS_CFG_REG_TYPE_RESOURCE 0x40 /* reg is a resource */ -#define CS_CFG_REG_TYPE_VAL_PARAM 0x08 /* reg value uses param */ -#define CS_CFG_REG_TYPE_VAL_MASK 0x04 /* reg value bit masked */ -#define CS_CFG_REG_TYPE_VAL_64BIT 0x02 /* reg value 64 bit */ -#define CS_CFG_REG_TYPE_VAL_SAVE 0x01 /* reg value save on disable */ - -/* - * flags defining what device class a feature will match to when processin= g a - * system configuration - used by config data and devices. - */ -#define CS_CFG_MATCH_CLASS_SRC_ALL 0x0001 /* match any source */ -#define CS_CFG_MATCH_CLASS_SRC_ETM4 0x0002 /* match any ETMv4 device */ - -/* flags defining device instance matching - used in config match desc dat= a. */ -#define CS_CFG_MATCH_INST_ANY 0x80000000 /* any instance of a class */ - -/* - * Limit number of presets in a configuration - * This is related to the number of bits (4) we use to select the preset on - * the perf command line. Preset 0 is always none selected. - * See PMU_FORMAT_ATTR(preset, "config:0-3") in coresight-etm-perf.c - */ -#define CS_CFG_CONFIG_PRESET_MAX 15 - -/** - * Parameter descriptor for a device feature. - * - * @name: Name of parameter. - * @value: Initial or default value. - */ -struct cscfg_parameter_desc { - const char *name; - u64 value; -}; - -/** - * Representation of register value and a descriptor of register usage. - * - * Used as a descriptor in the feature descriptors. - * Used as a value in when in a feature loading into a csdev. - * - * Supports full 64 bit register value, or 32 bit value with optional mask - * value. - * - * @type: define register usage and interpretation. - * @offset: the address offset for register in the hardware device (per de= vice specification). - * @hw_info: optional hardware device type specific information. (ETM / CT= I specific etc) - * @val64: 64 bit value. - * @val32: 32 bit value. - * @mask32: 32 bit mask when using 32 bit value to access device register = - if mask type. - * @param_idx: parameter index value into parameter array if param type. - */ -struct cscfg_regval_desc { - struct { - u32 type:8; - u32 offset:12; - u32 hw_info:12; - }; - union { - u64 val64; - struct { - u32 val32; - u32 mask32; - }; - u32 param_idx; - }; -}; - -/** - * Dynamically loaded descriptor arrays. - * - * For builtin or module loaded configurations / features these are - * statically defined at compile time. +/* common descriptor definitions */ +#include "coresight-config-desc.h" =20 - * For a dynamic load at runtime, using a config table, (e.g. load from - * configfs) we create the arrays dynamically so need a structure to - * manage these. - * - * @config_descs: array of config descriptor pointers. - * @feat_descs: array of feature descriptor pointers. - * @load_name: user readable name which may be used to unload later. - * Will be name of first config if present, or first feature. - */ -struct cscfg_table_load_descs { - struct cscfg_config_desc **config_descs; - struct cscfg_feature_desc **feat_descs; - char *load_name; -}; +/* CoreSight Configuration Management - component and system wide configur= ation */ =20 /** * Device feature descriptor - combination of registers and parameters to @@ -280,4 +189,26 @@ void cscfg_csdev_disable_config(struct cscfg_config_cs= dev *config_csdev); /* reset a feature to default values */ void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev); =20 + +/* Kernel allocators for descriptors in common config table read code */ +static inline void *cscfg_calloc(size_t num, size_t size) +{ + return kcalloc(num, size, GFP_KERNEL); +} + +static inline char *cscfg_strdup(const char *str) +{ + return kstrdup(str, GFP_KERNEL); +} + +static inline void *cscfg_zalloc(size_t size) +{ + return kzalloc(size, GFP_KERNEL); +} + +static inline void cscfg_free(void *mem) +{ + kfree(mem); +} + #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */ --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38C621FDE2B for ; Wed, 27 Nov 2024 13:43:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714993; cv=none; b=XCWzP9/LkZvBU2pap4D7bWpmuyIzf8f9NK3457tVmZAFz+O8hPMwBrUfTyAEw68Dgp/9hBeyI+eVTt5DPzNb8viJVtS8ABv9yWCb/xqXumLn3Fg+aPq4FGfBCi4Po8C4ZwkhblPkSuFfxo6KvufZNY6tLN3KlidmJ0qCZZ/+lKQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714993; c=relaxed/simple; bh=bCjNdPAyXaqp/moo81/tuzqjHlB4vZOR/j9FAkyAsk0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dO/DohOLyOoTDbswFcivlNw4TOgARhVuD7j2JfrMV03IEbcadVSgS0q11RsorsP2ebEzkxlqm+RTI0LYDFQADuq3oZOtNCmLu/MAVjyOlXxwuiipSBPQ5/cjjviB4y4VSbPh591BQig5fydGPlFqetE3YFInCFP3CLvbyBHWeOM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=Qvc/C3yl; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="Qvc/C3yl" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-434aa222d96so8277835e9.0 for ; Wed, 27 Nov 2024 05:43:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714988; x=1733319788; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=b7do7yGcfCic5M1WcR1wYgIJtxjffIMJzcsuDi7uwVQ=; b=Qvc/C3yllBm2GgZAR7DY6+aTPjq2YkVo0Ji9yBelycVKpmybqsa8AdjMQ+bYl9eMvp sB/94mSyIJmZtN6b1B9ImzWgA8oJiIbTxa4YZomxBNYtsDHP4TYjW+FDXCl0Nv85dCmH 8iGbKgzl1BNC5ScozkV9Rz9++iHT2o/eGHSojP0dEcm4sRTJXe4B58eDb4PuPIdkB2Tv jc0+W/xWQo43OV+XdHHXPMOfoVw+NTgP7m4pUacMiLEko32XQaxfno5NvR7TZEzkMgl7 m3GLrFz4QjEVFa8CZRzlbQjY2m7a4tZoCGLcpOCQ1ncGU5tXn12MvhC9MuBpvJpfHAGK bNvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714988; x=1733319788; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=b7do7yGcfCic5M1WcR1wYgIJtxjffIMJzcsuDi7uwVQ=; b=KGmFOpuB+P4X9bmYFjgaI6ylfzV7le3h916CJfBMoyxKdTRKO4fCkbQI4jIIDIEFWh A5w6FW1IrFPz69KMLa1Mz2Cfjequ2ijZi4VJgsOVWOpY82rRI8F0+nYSQcuwmhwDZhsU waYgdDi1CBwZpjxxSSkVZQP61CB2B4MC/PL+/ln3lbz2DWUtYa7HVxDbmGQJTHvLnmPp L3VQNd7OEMTLbDhv1qWc5cFf403fkgFOAumD4Vn5jSr5Jr0arP//SkEMAMc9KmtbVGDU TuR9tmIGnbf3Hpz8rCMhdnd8ZbcKaB7H+yvRX7czqQyN9Zj6V04Mank5hiaJOOS/B+Vn oeDg== X-Forwarded-Encrypted: i=1; AJvYcCV2o1w5JrPlp0k6SJnQKriBKjy4bjXHzboyhc4xq7Ybg/hyxgGUCsGukTUzoZvQCavuQfBL6dcc+791wF0=@vger.kernel.org X-Gm-Message-State: AOJu0YyguHKu8a7p5HutMYn/PuND+OJ/9m/93OiOCd4QDmOZEUMmZI1Y NvSfQ4JxpVoGnHjatRwdYG1hrUaLeueS+zTPSAi8Pv0CO6E2XS0xQ1nIGvWgCGI= X-Gm-Gg: ASbGncs6nNCGEh5efOzMvJkOST5Gxy3auD0/I3p7Ec4HdRYq67NqoHj5LDEPVMH4hzb qX8k9ebFQJoJto/eizu/JrQSYBiLySiKcIZ+A+q8NLzOHJDW8+6NkGAVx7DVriNa3/uXaRvUdzF HyBPZtXVrgKjsANgwwA8kUiJeGYzT0Yaivr/CorMk7TfRnXPo3SCD6dx7WeSI0UXIQgVRsWfctN 88lpV3oupY9ooamRKdDNjmMfKcrKNy0dr8Yj0phjPpkNu5vgcTh X-Google-Smtp-Source: AGHT+IE95ZTsUMG+YQJ2vUcIv9oSh/sh9Sh2yNkTBnaiA1qw76pziEvZRGbI0BTyvbVIUvO7OOa03A== X-Received: by 2002:a05:6000:2b12:b0:382:506b:f627 with SMTP id ffacd0b85a97d-385c6edd72fmr2175769f8f.57.1732714988225; Wed, 27 Nov 2024 05:43:08 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:07 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach Subject: [PATCH v7 8/9] coresight: tools: Add configuration table test tools Date: Wed, 27 Nov 2024 13:42:55 +0000 Message-Id: <20241127134256.2254851-9-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an example config table generator to test loading configuration tables. Provides a table buffer writer function that can be re-used in other userspace programs. Table write format matches that expected by the corresponding reader in the configfs driver code. Generates tables and outputs in form of binary files. Add a config table file reader and printer. Takes in config table files and prints the contents. Uses table reader source from kernel driver. Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- MAINTAINERS | 1 + .../coresight/coresight-config-table.h | 5 + tools/coresight/Makefile | 56 +++ tools/coresight/coresight-cfg-bufw.c | 328 ++++++++++++++++++ tools/coresight/coresight-cfg-bufw.h | 26 ++ tools/coresight/coresight-cfg-example1.c | 62 ++++ tools/coresight/coresight-cfg-example2.c | 95 +++++ tools/coresight/coresight-cfg-examples.h | 25 ++ tools/coresight/coresight-cfg-file-gen.c | 58 ++++ tools/coresight/coresight-cfg-file-gen.h | 17 + tools/coresight/coresight-cfg-file-read.c | 239 +++++++++++++ tools/coresight/coresight-config-uapi.h | 105 ++++++ 12 files changed, 1017 insertions(+) create mode 100644 tools/coresight/Makefile create mode 100644 tools/coresight/coresight-cfg-bufw.c create mode 100644 tools/coresight/coresight-cfg-bufw.h create mode 100644 tools/coresight/coresight-cfg-example1.c create mode 100644 tools/coresight/coresight-cfg-example2.c create mode 100644 tools/coresight/coresight-cfg-examples.h create mode 100644 tools/coresight/coresight-cfg-file-gen.c create mode 100644 tools/coresight/coresight-cfg-file-gen.h create mode 100644 tools/coresight/coresight-cfg-file-read.c create mode 100644 tools/coresight/coresight-config-uapi.h diff --git a/MAINTAINERS b/MAINTAINERS index e9659a5a7fb3..8b848694394e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2301,6 +2301,7 @@ F: include/dt-bindings/arm/coresight-cti-dt.h F: include/linux/coresight* F: include/uapi/linux/coresight* F: samples/coresight/* +F: tools/coresight/* F: tools/perf/Documentation/arm-coresight.txt F: tools/perf/arch/arm/util/auxtrace.c F: tools/perf/arch/arm/util/cs-etm.c diff --git a/drivers/hwtracing/coresight/coresight-config-table.h b/drivers= /hwtracing/coresight/coresight-config-table.h index 2cd8fb0630e2..b9935bff7169 100644 --- a/drivers/hwtracing/coresight/coresight-config-table.h +++ b/drivers/hwtracing/coresight/coresight-config-table.h @@ -9,7 +9,12 @@ =20 #include =20 +#ifdef __KERNEL__ #include "coresight-config.h" +#else +#include "coresight-config-uapi.h" +#endif + =20 /* * Configurations and features can be dynamically loaded at runtime diff --git a/tools/coresight/Makefile b/tools/coresight/Makefile new file mode 100644 index 000000000000..175d2b45bb44 --- /dev/null +++ b/tools/coresight/Makefile @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: GPL-2.0-only +include ../scripts/Makefile.include +include ../scripts/Makefile.arch + +# Makefile to build the coresight configuration table file reader and gene= rator tools + +this-makefile :=3D $(lastword $(MAKEFILE_LIST)) +tools-src :=3D $(realpath $(dir $(this-makefile))) +srctree :=3D $(realpath $(dir $(tools-src)/../../.)) + +# ensure we use all as the default - skip anything in included Makefile +.DEFAULT_GOAL =3D all +# MAKECMDGOALS isn't set if there's no explicit goal in the +# command line, so set the default. +MAKECMDGOALS ?=3D $(.DEFAULT_GOAL) + +# cs tools includes +CS_TOOLS_INCLUDE =3D -I$(srctree)/drivers/hwtracing/coresight -I$(srctree)= /tools/include/ \ + -I$(srctree)/tools/include/uapi -I$(srctree)/tools/coresight + +# compile flags +CFLAGS +=3D $(CPPFLAGS) -c -Wall -DLINUX -Wno-switch -Wlogical-op -fPIC $(= CS_TOOLS_INCLUDE) + +# object files +coresight-cfg-file-gen-objs :=3D coresight-cfg-file-gen.o coresight-cfg-bu= fw.o \ + coresight-cfg-example1.o coresight-cfg-example2.o +coresight-cfg-file-read-objs :=3D coresight-cfg-file-read.o coresight-conf= ig-table.o + +# debug variant +ifdef DEBUG +CFLAGS +=3D -g -O0 -DDEBUG +else +CFLAGS +=3D -O2 -DNDEBUG +endif + +.PHONY: all +all: coresight-cfg-file-gen coresight-cfg-file-read + +coresight-config-table.o: src_copy + $(CC) $(CFLAGS) coresight-config-table.c -o coresight-config-table.o + +.PHONY: src_copy +src_copy: + @cp $(srctree)/drivers/hwtracing/coresight/coresight-config-table.c $(src= tree)/tools/coresight/. + +coresight-cfg-file-gen: $(coresight-cfg-file-gen-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-file-gen-objs) -o coresight-cfg-file-gen + +coresight-cfg-file-read: $(coresight-cfg-file-read-objs) + $(CC) $(LDFLAGS) $(coresight-cfg-file-read-objs) -o coresight-cfg-file-re= ad + +clean: + rm -f coresight-cfg-file-gen coresight-cfg-file-read + rm -f *.o + rm -f coresight-config-table.c + rm -f *.cscfg diff --git a/tools/coresight/coresight-cfg-bufw.c b/tools/coresight/coresig= ht-cfg-bufw.c new file mode 100644 index 000000000000..3fa7ee968758 --- /dev/null +++ b/tools/coresight/coresight-cfg-bufw.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include + +#include "coresight-cfg-bufw.h" +#include "coresight-config-uapi.h" + +/* + * Set of macros to make writing the buffer code easier. + *. + * Uses naming convention as 'buffer' for the buffer pointer and + * 'used' as the current bytes used by the encosing function. + */ +#define cscfg_write_u64(val64) { \ + *(u64 *)(buffer + used) =3D val64; \ + used +=3D sizeof(u64); \ + } + +#define cscfg_write_u32(val32) { \ + *(u32 *)(buffer + used) =3D val32; \ + used +=3D sizeof(u32); \ + } + +#define cscfg_write_u16(val16) { \ + *(u16 *)(buffer + used) =3D val16; \ + used +=3D sizeof(u16); \ + } + +#define cscfg_write_u8(val8) { \ + *(buffer + used) =3D val8; \ + used++; \ + } + +/* write the header at the start of the buffer */ +static int cscfg_table_write_fhdr(u8 *buffer, const int buflen, + const struct cscfg_table_header *fhdr) +{ + int used =3D 0; + + cscfg_write_u32(fhdr->magic_version); + cscfg_write_u16(fhdr->length); + cscfg_write_u16(fhdr->nr_configs); + cscfg_write_u16(fhdr->nr_features); + return used; +} + +static int cscfg_table_write_string(u8 *buffer, const int buflen, const ch= ar *string) +{ + int len, used =3D 0; + + len =3D strlen(string); + if (len > CSCFG_TABLE_STR_MAXSIZE) + return -EINVAL; + + if (buflen < (len + 1 + sizeof(u16))) + return -EINVAL; + + cscfg_write_u16((u16)(len + 1)); + strncpy((char *)(buffer + used), string, len + 1); + used +=3D (len + 1); + + return used; +} + +static int cscfg_table_write_elem_hdr(u8 *buffer, const int buflen, + struct cscfg_table_elem_header *ehdr) +{ + int used =3D 0; + + if (buflen < (sizeof(u16) + sizeof(u8))) + return -EINVAL; + + cscfg_write_u16(ehdr->elem_length); + cscfg_write_u8(ehdr->elem_type); + + return used; +} + +static int cscfg_table_write_config(u8 *buffer, const int buflen, + struct cscfg_config_desc *config_desc) +{ + int used =3D 0, bytes_w, space_req, preset_bytes, i; + struct cscfg_table_elem_header ehdr; + + ehdr.elem_length =3D 0; + ehdr.elem_type =3D CSCFG_TABLE_ELEM_TYPE_CFG; + + /* write element header at current buffer location */ + bytes_w =3D cscfg_table_write_elem_hdr(buffer, buflen, &ehdr); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* write out the configuration name */ + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + config_desc->name); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* write out the description string */ + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + config_desc->description); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* + * calculate the space needed for variables + presets + * [u16 value - nr_presets] + * [u32 value - nr_total_params] + * [u16 value - nr_feat_refs] + * [u64 values] * (nr_presets * nr_total_params) + */ + preset_bytes =3D sizeof(u64) * config_desc->nr_presets * config_desc->nr_= total_params; + space_req =3D (sizeof(u16) * 2) + sizeof(u32) + preset_bytes; + + if ((buflen - used) < space_req) + return -EINVAL; + + cscfg_write_u16((u16)config_desc->nr_presets); + cscfg_write_u32((u32)config_desc->nr_total_params); + cscfg_write_u16((u16)config_desc->nr_feat_refs); + if (preset_bytes) { + memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes); + used +=3D preset_bytes; + } + + /* now write the feature ref names */ + for (i =3D 0; i < config_desc->nr_feat_refs; i++) { + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + config_desc->feat_ref_names[i]); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + } + + /* rewrite the element header with the correct length */ + ehdr.elem_length =3D used; + bytes_w =3D cscfg_table_write_elem_hdr(buffer, buflen, &ehdr); + /* used must not be updated here */ + if (bytes_w < 0) + return bytes_w; + + return used; +} + +/* + * write a parameter structure into the buffer in following format: + * [cscfg_table_elem_str] - parameter name. + * [u64 value: param_value] - initial value. + */ +static int cscfg_table_write_param(u8 *buffer, const int buflen, + struct cscfg_parameter_desc *param_desc) +{ + int used =3D 0, bytes_w; + + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + param_desc->name); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + if ((buflen - used) < sizeof(u64)) + return -EINVAL; + + cscfg_write_u64(param_desc->value); + return used; +} + +/* + * Write a feature element from cscfg_feature_desc in following format: + * + * [cscfg_table_elem_header] - header length is total bytes to end of para= m structures. + * [cscfg_table_elem_str] - feature name. + * [cscfg_table_elem_str] - feature description. + * [u32 value: match_flags] + * [u16 value: nr_regs] - number of registers. + * [u16 value: nr_params] - number of parameters. + * [cscfg_regval_desc struct] * nr_regs + * [PARAM_ELEM] * nr_params + */ +static int cscfg_table_write_feat(u8 *buffer, const int buflen, + struct cscfg_feature_desc *feat_desc) +{ + struct cscfg_table_elem_header ehdr; + struct cscfg_regval_desc *p_reg_desc; + int used =3D 0, bytes_w, i, space_req; + u32 val32; + + ehdr.elem_length =3D 0; + ehdr.elem_type =3D CSCFG_TABLE_ELEM_TYPE_FEAT; + + /* write element header at current buffer location */ + bytes_w =3D cscfg_table_write_elem_hdr(buffer, buflen, &ehdr); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* write out the name string */ + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + feat_desc->name); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* write out the description string */ + bytes_w =3D cscfg_table_write_string(buffer + used, buflen - used, + feat_desc->description); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* check for space for variables and register structures */ + space_req =3D (sizeof(u16) * 2) + sizeof(u32) + + (sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs); + if ((buflen - used) < space_req) + return -EINVAL; + + /* write the variables */ + cscfg_write_u32((u32)feat_desc->match_flags); + cscfg_write_u16((u16)feat_desc->nr_regs); + cscfg_write_u16((u16)feat_desc->nr_params); + + /*write the registers */ + for (i =3D 0; i < feat_desc->nr_regs; i++) { + p_reg_desc =3D (struct cscfg_regval_desc *)&feat_desc->regs_desc[i]; + CSCFG_TABLE_REG_DESC_INFO_TO_U32(val32, p_reg_desc); + cscfg_write_u32(val32); + cscfg_write_u64(feat_desc->regs_desc[i].val64); + } + + /* write any parameters */ + for (i =3D 0; i < feat_desc->nr_params; i++) { + bytes_w =3D cscfg_table_write_param(buffer + used, buflen - used, + &feat_desc->params_desc[i]); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + } + + /* + * rewrite the element header at the start of the buffer block + * with the correct length + */ + ehdr.elem_length =3D used; + bytes_w =3D cscfg_table_write_elem_hdr(buffer, buflen, &ehdr); + /* used must not be updated here */ + if (bytes_w < 0) + return bytes_w; + + return used; +} + +/* + * write a buffer from the configuration and feature + * descriptors to write into a file for configfs. + * + * Will only write one config, and/or a number of features, + * per the file standard. + */ +int cscfg_table_write_buffer(u8 *buffer, const int buflen, + struct cscfg_config_desc **config_descs, + struct cscfg_feature_desc **feat_descs) +{ + struct cscfg_table_header fhdr; + int used =3D 0, bytes_w, i; + + /* init the file header */ + fhdr.magic_version =3D CSCFG_TABLE_MAGIC_VERSION; + fhdr.length =3D 0; + fhdr.nr_configs =3D 0; + fhdr.nr_features =3D 0; + + /* count the configs */ + if (config_descs) { + while (config_descs[fhdr.nr_configs]) + fhdr.nr_configs++; + } + + /* count the features */ + if (feat_descs) { + while (feat_descs[fhdr.nr_features]) + fhdr.nr_features++; + } + + /* need a buffer and at least one config or feature */ + if ((!fhdr.nr_configs && !fhdr.nr_features) || + !buffer || (buflen > CSCFG_TABLE_MAXSIZE)) + return -EINVAL; + + /* write a header at the start to get the length of the header */ + bytes_w =3D cscfg_table_write_fhdr(buffer, buflen, &fhdr); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + + /* write configs */ + for (i =3D 0; i < fhdr.nr_configs; i++) { + bytes_w =3D cscfg_table_write_config(buffer + used, buflen - used, + config_descs[i]); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + } + + /* write any features */ + for (i =3D 0; i < fhdr.nr_features; i++) { + bytes_w =3D cscfg_table_write_feat(buffer + used, buflen - used, + feat_descs[i]); + if (bytes_w < 0) + return bytes_w; + used +=3D bytes_w; + } + + /* finally re-write the header at the buffer start with the correct lengt= h */ + fhdr.length =3D (u16)used; + bytes_w =3D cscfg_table_write_fhdr(buffer, buflen, &fhdr); + /* used must not be updated here */ + if (bytes_w < 0) + return bytes_w; + return used; +} diff --git a/tools/coresight/coresight-cfg-bufw.h b/tools/coresight/coresig= ht-cfg-bufw.h new file mode 100644 index 000000000000..2d6ce64220a4 --- /dev/null +++ b/tools/coresight/coresight-cfg-bufw.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CFG_BUFW_H +#define _CORESIGHT_CFG_BUFW_H + +#include + +#include "coresight-config-table.h" + +/* + * Function to take coresight configurations and features and + * write them into a supplied memory buffer for serialisation + * into a file. + * + * Resulting file can then be loaded into the coresight + * infrastructure via configfs. + */ +int cscfg_table_write_buffer(u8 *buffer, const int buflen, + struct cscfg_config_desc **config_descs, + struct cscfg_feature_desc **feat_descs); + +#endif /* _CORESIGHT_CFG_BUFW_H */ diff --git a/tools/coresight/coresight-cfg-example1.c b/tools/coresight/cor= esight-cfg-example1.c new file mode 100644 index 000000000000..c562116ffc94 --- /dev/null +++ b/tools/coresight/coresight-cfg-example1.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ +#include +#include +#include +#include + +#include "coresight-cfg-examples.h" + +/* + * create a configuration only example using the strobing feature + */ + +/* we will provide 4 sets of preset parameter values */ +#define AFDO3_NR_PRESETS 4 +/* the total number of parameters in used features - strobing has 2 */ +#define AFDO3_NR_PARAM_SUM 2 + +static const char *afdo3_ref_names[] =3D { + "strobing", +}; + +/* + * set of presets leaves strobing window constant while varying period to = allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo3_presets[AFDO3_NR_PRESETS][AFDO3_NR_PARAM_SUM] =3D { + { 2000, 100 }, + { 2000, 1000 }, + { 2000, 5000 }, + { 2000, 10000 }, +}; + +struct cscfg_config_desc afdo3 =3D { + .name =3D "autofdo3", + .description =3D "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various= loads\n", + .nr_feat_refs =3D ARRAY_SIZE(afdo3_ref_names), + .feat_ref_names =3D afdo3_ref_names, + .nr_presets =3D AFDO3_NR_PRESETS, + .nr_total_params =3D AFDO3_NR_PARAM_SUM, + .presets =3D &afdo3_presets[0][0], +}; + +static struct cscfg_feature_desc *sample_feats[] =3D { + NULL +}; + +static struct cscfg_config_desc *sample_cfgs[] =3D { + &afdo3, + NULL +}; + +struct cscfg_file_eg_info file_info_eg1 =3D { + .example_name =3D "example1", + .filename =3D "example1.cscfg", + .config_descs =3D sample_cfgs, + .feat_descs =3D sample_feats, +}; diff --git a/tools/coresight/coresight-cfg-example2.c b/tools/coresight/cor= esight-cfg-example2.c new file mode 100644 index 000000000000..6312a185bd46 --- /dev/null +++ b/tools/coresight/coresight-cfg-example2.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ +#include +#include +#include +#include + +#include "coresight-cfg-examples.h" + +/* + * create a dual configuration only example using the strobing feature + */ + +/* we will provide 10 sets of preset parameter values */ +#define AFDO_NR_PRESETS 10 +/* the total number of parameters in used features - strobing has 2 */ +#define AFDO_NR_PARAM_SUM 2 + +static const char *afdo_ref_names[] =3D { + "strobing", +}; + +/* + * sets of presets leaves strobing window constant while varying period to= allow + * experimentation with mark / space ratios for various workloads + */ +static u64 afdo_set_a_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] =3D { + { 2000, 100 }, + { 2000, 1000 }, + { 2000, 5000 }, + { 2000, 10000 }, + { 4000, 100 }, + { 4000, 1000 }, + { 4000, 5000 }, + { 4000, 10000 }, + { 6000, 100 }, + { 6000, 1000 }, +}; + + +static u64 afdo_set_b_presets[AFDO_NR_PRESETS][AFDO_NR_PARAM_SUM] =3D { + { 6000, 5000 }, + { 6000, 10000 }, + { 8000, 100 }, + { 8000, 1000 }, + { 8000, 5000 }, + { 8000, 10000 }, + { 12000, 100 }, + { 12000, 1000 }, + { 12000, 5000 }, + { 12000, 10000 }, +}; +/* two configurations with differing preset tables */ +struct cscfg_config_desc afdo_seta =3D { + .name =3D "autofdo_set_a", + .description =3D "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various= loads\n", + .nr_feat_refs =3D ARRAY_SIZE(afdo_ref_names), + .feat_ref_names =3D afdo_ref_names, + .nr_presets =3D AFDO_NR_PRESETS, + .nr_total_params =3D AFDO_NR_PARAM_SUM, + .presets =3D &afdo_set_a_presets[0][0], +}; + +struct cscfg_config_desc afdo_setb =3D { + .name =3D "autofdo_set_b", + .description =3D "Setup ETMs with strobing for autofdo\n" + "Supplied presets allow experimentation with mark-space ratio for various= loads\n", + .nr_feat_refs =3D ARRAY_SIZE(afdo_ref_names), + .feat_ref_names =3D afdo_ref_names, + .nr_presets =3D AFDO_NR_PRESETS, + .nr_total_params =3D AFDO_NR_PARAM_SUM, + .presets =3D &afdo_set_b_presets[0][0], +}; + + +static struct cscfg_feature_desc *sample_feats[] =3D { + NULL +}; + +static struct cscfg_config_desc *sample_cfgs[] =3D { + &afdo_seta, + &afdo_setb, + NULL +}; + +struct cscfg_file_eg_info file_info_eg2 =3D { + .example_name =3D "example2", + .filename =3D "example2.cscfg", + .config_descs =3D sample_cfgs, + .feat_descs =3D sample_feats, +}; diff --git a/tools/coresight/coresight-cfg-examples.h b/tools/coresight/cor= esight-cfg-examples.h new file mode 100644 index 000000000000..c9719e7b2233 --- /dev/null +++ b/tools/coresight/coresight-cfg-examples.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CFG_EXAMPLES_H +#define _CORESIGHT_CFG_EXAMPLES_H + +#include + +#include "coresight-config-uapi.h" + +/* + * structure to pass C configuration structure information to + * configuration table file generator program + */ +struct cscfg_file_eg_info { + const char *example_name; + const char *filename; + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; +}; + +#endif /* _CORESIGHT_CFG_EXAMPLES_H */ diff --git a/tools/coresight/coresight-cfg-file-gen.c b/tools/coresight/cor= esight-cfg-file-gen.c new file mode 100644 index 000000000000..c93487d35cee --- /dev/null +++ b/tools/coresight/coresight-cfg-file-gen.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include +#include +#include +#include + +#include "coresight-cfg-bufw.h" +#include "coresight-cfg-examples.h" +#include "coresight-cfg-file-gen.h" + +/* array of example table files to generate */ +struct cscfg_file_eg_info *info_ptrs[] =3D { + &file_info_eg1, + &file_info_eg2, + NULL, +}; + +int main(int argc, char **argv) +{ + struct cscfg_config_desc **config_descs; + struct cscfg_feature_desc **feat_descs; + u8 buffer[CSCFG_TABLE_MAXSIZE]; + int used, idx =3D 0; + FILE *fp; + const char *filename; + + printf("Coresight Configuration table file Generator\n\n"); + + while (info_ptrs[idx]) { + printf("Generating %s example\n", info_ptrs[idx]->example_name); + config_descs =3D info_ptrs[idx]->config_descs; + feat_descs =3D info_ptrs[idx]->feat_descs; + filename =3D info_ptrs[idx]->filename; + used =3D cscfg_table_write_buffer(buffer, CSCFG_TABLE_MAXSIZE, + config_descs, feat_descs); + + if (used < 0) { + printf("Error %d writing configuration %s into buffer\n", + used, info_ptrs[idx]->example_name); + return used; + } + + fp =3D fopen(filename, "wb"); + if (fp =3D=3D NULL) { + printf("Error opening file %s\n", filename); + return -1; + } + fwrite(buffer, used, sizeof(u8), fp); + fclose(fp); + idx++; + } + return 0; +} diff --git a/tools/coresight/coresight-cfg-file-gen.h b/tools/coresight/cor= esight-cfg-file-gen.h new file mode 100644 index 000000000000..e823e9c5c508 --- /dev/null +++ b/tools/coresight/coresight-cfg-file-gen.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CFG_FILE_GEN_H +#define _CORESIGHT_CFG_FILE_GEN_H + +/* + * references to the configuration and feature example + * structures in example source files + */ +extern struct cscfg_file_eg_info file_info_eg1; +extern struct cscfg_file_eg_info file_info_eg2; + +#endif /* _CORESIGHT_CFG_FILE_GEN_H */ diff --git a/tools/coresight/coresight-cfg-file-read.c b/tools/coresight/co= resight-cfg-file-read.c new file mode 100644 index 000000000000..153af8a16e65 --- /dev/null +++ b/tools/coresight/coresight-cfg-file-read.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020-2022 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "coresight-config-table.h" +#include "coresight-config-uapi.h" + +/* + * tool to read and print a generated configuration + * re-uses the read code source from the driver. + */ + +static void validate_config_name(const char *name) +{ + int i, len =3D strlen(name); + + for (i =3D 0; i < len; i++) { + if (!isalnum(name[i]) && !(name[i] =3D=3D '_')) { + printf("\n************************************************\n"); + printf("ERROR: Configuration name %s invalid character(s)\n", name); + printf(" : must contain only alphanumeric and _ only\n"); + printf("************************************************\n"); + } + } +} + +static void print_configs(struct cscfg_table_load_descs *load_descs, int *= nr_configs) +{ + struct cscfg_config_desc *config_desc; + int i, j, p, cfg_idx =3D 0; + + *nr_configs =3D 0; + config_desc =3D load_descs->config_descs[cfg_idx]; + if (!config_desc) { + printf("File contains no configurations.\n\n"); + return; + } + + while (config_desc) { + printf("Configuration %d\nName:- %s\n", cfg_idx + 1, config_desc->name); + validate_config_name(config_desc->name); + printf("Description:-\n%s\n", config_desc->description); + printf("Uses %d features:-\n", config_desc->nr_feat_refs); + for (i =3D 0; i < config_desc->nr_feat_refs; i++) + printf("Feature-%d: %s\n", i + 1, config_desc->feat_ref_names[i]); + + printf("\nProvides %d sets of preset values, %d presets per set\n", + config_desc->nr_presets, config_desc->nr_total_params); + if (config_desc->nr_presets) { + for (i =3D 0; i < config_desc->nr_presets; i++) { + printf("set[%d]: ", i); + for (j =3D 0; j < config_desc->nr_total_params; j++) { + p =3D (i * config_desc->nr_total_params) + j; + printf("0x%lx, ", config_desc->presets[p]); + } + printf("\n"); + } + } + printf("\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"= ); + cfg_idx++; + config_desc =3D load_descs->config_descs[cfg_idx]; + (*nr_configs)++; + } +} + +static void print_reg_type_info(u8 type) +{ + if (type & CS_CFG_REG_TYPE_STD) + printf("std_reg "); + if (type & CS_CFG_REG_TYPE_RESOURCE) + printf("resource "); + if (type & CS_CFG_REG_TYPE_VAL_PARAM) + printf("param_index "); + if (type & CS_CFG_REG_TYPE_VAL_64BIT) + printf("64_bit "); + else + printf("32_bit "); + if (type & CS_CFG_REG_TYPE_VAL_MASK) + printf("masked "); + if (type & CS_CFG_REG_TYPE_VAL_SAVE) + printf("save_on_disable "); + +} + +static void print_regs(int nr, struct cscfg_regval_desc *regs_desc_array) +{ + int i; + struct cscfg_regval_desc *reg_desc; + u8 type; + u16 offset; + u16 info; + + for (i =3D 0; i < nr; i++) { + reg_desc =3D ®s_desc_array[i]; + type =3D (u8)reg_desc->type; + offset =3D (u16)reg_desc->offset; + info =3D (u16)reg_desc->hw_info; + + printf("Reg(%d): Type 0x%x: ", i, type); + print_reg_type_info(type); + printf("\nOffset: 0x%03x; HW Info: 0x%03x\n", offset, info); + printf("Value: "); + if (type & CS_CFG_REG_TYPE_VAL_64BIT) + printf("0x%lx\n", reg_desc->val64); + else if (type & CS_CFG_REG_TYPE_VAL_PARAM) { + printf("param(%d) ", reg_desc->param_idx); + if (type & (CS_CFG_REG_TYPE_VAL_MASK)) + printf(" mask: 0x%x", reg_desc->mask32); + printf("\n"); + } else { + printf("0x%x ", reg_desc->val32); + if (type & (CS_CFG_REG_TYPE_VAL_MASK)) + printf(" mask: 0x%x", reg_desc->mask32); + printf("\n"); + } + } +} + +static void print_params(int nr, struct cscfg_parameter_desc *params_desc) +{ + int i; + + for (i =3D 0; i < nr; i++) + printf("Param(%d) : %s; Init value 0x%lx\n", i, + params_desc[i].name, params_desc[i].value); +} + +static void print_features(struct cscfg_table_load_descs *load_descs, int = *nr_feats) +{ + struct cscfg_feature_desc *feat_desc =3D 0; + int idx =3D 0; + + *nr_feats =3D 0; + feat_desc =3D load_descs->feat_descs[idx]; + if (!feat_desc) { + printf("File contains no features\n\n"); + return; + } + + while (feat_desc) { + printf("Feature %d\nName:- %s\n\n", idx + 1, feat_desc->name); + printf("Description:- %s\n", feat_desc->description); + printf("Match flags: 0x%x\n", feat_desc->match_flags); + printf("\nNumber of Paraneters: %d\n", feat_desc->nr_params); + if (feat_desc->nr_params) + print_params(feat_desc->nr_params, feat_desc->params_desc); + printf("\nNumber of Registers: %d\n", feat_desc->nr_regs); + if (feat_desc->nr_regs) + print_regs(feat_desc->nr_regs, feat_desc->regs_desc); + printf("\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"= ); + + /* next feature */ + idx++; + feat_desc =3D load_descs->feat_descs[idx]; + (*nr_feats)++; + } +} + +int main(int argc, char **argv) +{ + FILE *fp; + struct cscfg_table_load_descs *load_descs; + int err, fsize, nr_configs =3D 0, nr_feats =3D 0; + u8 buffer[CSCFG_TABLE_MAXSIZE]; + + printf("\n\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"= ); + printf("CoreSight Configuration table file reader"); + printf("\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\n"); + + /* need a filename */ + if (argc <=3D 1) { + printf("Please provide filename on command line\n"); + return -EINVAL; + } + + /* open file and read into the buffer. */ + fp =3D fopen(argv[1], "rb"); + if (fp =3D=3D NULL) { + printf("Error opening file %s\n", argv[1]); + return -EINVAL; + } + + fseek(fp, 0, SEEK_END); + fsize =3D ftell(fp); + rewind(fp); + if (fsize > CSCFG_TABLE_MAXSIZE) { + printf("Error: Input file too large."); + fclose(fp); + return -EINVAL; + } + err =3D fread(buffer, sizeof(u8), fsize, fp); + fclose(fp); + + if (err < fsize) { + printf("Error reading file %s\n", argv[1]); + return -EINVAL; + } + + /* allocate the descriptor structures to be populated by read operation */ + load_descs =3D calloc(1, sizeof(struct cscfg_table_load_descs)); + if (!load_descs) { + printf("Error allocating load descs structure.\n"); + return -ENOMEM; + } + + /* read the buffer and create the configuration and feature structures */ + err =3D cscfg_table_read_buffer(buffer, fsize, load_descs); + if (err) { + printf("Error reading configuration file\n"); + goto exit_free_mem; + } + + /* print the contents of the structures */ + print_configs(load_descs, &nr_configs); + print_features(load_descs, &nr_feats); + + printf("\n\n=3D=3D=3D=3D=3D=3D=3D Summary =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"); + printf(" Config File Name: : %s\n", argv[1]); + printf(" Number of Configurations: %d\n", nr_configs); + printf(" Number of Features : %d\n", nr_feats); + printf(" Load name : %s\n", load_descs->load_name); + printf("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\n"); + + +exit_free_mem: + cscfg_table_free_load_descs(load_descs); + free(load_descs); + return err; +} diff --git a/tools/coresight/coresight-config-uapi.h b/tools/coresight/core= sight-config-uapi.h new file mode 100644 index 000000000000..f3698a5b10ef --- /dev/null +++ b/tools/coresight/coresight-config-uapi.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Linaro Limited, All rights reserved. + * Author: Mike Leach + */ + +#ifndef _CORESIGHT_CORESIGHT_CONFIG_UAPI_H +#define _CORESIGHT_CORESIGHT_CONFIG_UAPI_H + +#include +#include + +#include +#include +#include + +#include "coresight-config-desc.h" + +/* + * Userspace versions of the configuration and feature descriptors. + * Used in the tools/coresight programs. + * + * Compatible with structures in coresight-config.h for use in + * coresight-config-file.c common reader source file. + */ + +/** + * Device feature descriptor - combination of registers and parameters to + * program a device to implement a specific complex function. + * + * UAPI version - removed kernel constructs. + * + * @name: feature name. + * @description: brief description of the feature. + * @match_flags: matching information if loading into a device + * @nr_params: number of parameters used. + * @params_desc: array of parameters used. + * @nr_regs: number of registers used. + * @regs_desc: array of registers used. + */ +struct cscfg_feature_desc { + const char *name; + const char *description; + u32 match_flags; + int nr_params; + struct cscfg_parameter_desc *params_desc; + int nr_regs; + struct cscfg_regval_desc *regs_desc; +}; + +/** + * Configuration descriptor - describes selectable system configuration. + * + * A configuration describes device features in use, and may provide preset + * values for the parameters in those features. + * + * A single set of presets is the sum of the parameters declared by + * all the features in use - this value is @nr_total_params. + * + * UAPI version - removed kernel constructs. + * + * @name: name of the configuration - used for selection. + * @description: description of the purpose of the configuration. + * @nr_feat_refs: Number of features used in this configuration. + * @feat_ref_names: references to features used in this configuration. + * @nr_presets: Number of sets of presets supplied by this configuration. + * @nr_total_params: Sum of all parameters declared by used features + * @presets: Array of preset values. + */ +struct cscfg_config_desc { + const char *name; + const char *description; + int nr_feat_refs; + const char **feat_ref_names; + int nr_presets; + int nr_total_params; + const u64 *presets; /* nr_presets * nr_total_params */ +}; + +/* UAPI allocators for descriptors in common config file buffer read code = */ +static inline void *cscfg_calloc(size_t num, size_t size) +{ + return calloc(num, size); +} + +static inline char *cscfg_strdup(const char *str) +{ + return strdup(str); +} + +static inline void *cscfg_zalloc(size_t size) +{ + void *ptr =3D malloc(size); + + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +static inline void cscfg_free(void *mem) +{ + free(mem); +} + +#endif /* _CORESIGHT_CORESIGHT_CONFIG_UAPI_H */ --=20 2.25.1 From nobody Mon Feb 9 03:46:22 2026 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 379811FE449 for ; Wed, 27 Nov 2024 13:43:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714995; cv=none; b=CdWUxgGbwW9ixKj9WusNsOdkptTqSB2u+0m1LYIDaFzxiU8nuRSAUhKSmOwzySIeekDYBa/4fBhPQknuSkEg1aiso/dqARbvwHgirZTUQLXSjNbF7v54mTvvErJtaJQFiL7RlHKceDHUIQBlNmxjYObNw3qaOWf9syhI63Oc4Fg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732714995; c=relaxed/simple; bh=DLkjziN79QL8lyYnpS+eq3WKuIQ9MNA9OHMlkX9yOnk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=stfEbNH76ujF5wfY926F1h+Gj5SCzDxgPrxTpokuNFuX9m84gGhMTJA38hMOgXl7VdKPqQRLAzz8uE7KCWw2Oy5ixdfjglOnJ9zUIql2Lc/6yl0W0J0bLMemvwqxzIQn0ycqece+64Dt6xdBwGpV75LvU9bZLdxkbzPjAd4WDYY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=ndtL5tA1; arc=none smtp.client-ip=209.85.221.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="ndtL5tA1" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-38241435528so4271112f8f.2 for ; Wed, 27 Nov 2024 05:43:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732714989; x=1733319789; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7njX2qcYZvO6vOSLv4oNfTTNGnncqtHXP/PHkDETIWA=; b=ndtL5tA1X7PVwATf3f/NUAnlzE34wMKRzMssjeEOH9AF8lmtEpM3GUR97qbs+S19xi dsy2tDpwc94/QyZVCi4NcneILLOPuBC7TcwND3FfgCUmHqoEHteMstzc/uiMPaQdaTWf svdVvC2a18jDuIAyKkLYPY3motQt0RA/ZriJW9HaYJoOEYzCKIGkbJjG3DvlA4/bkQZ2 /ZE7lI5NDC+qJYS/wMdCOQrcb4TuVXxNScAUm85Xk0JFR0cxP7jbYAfODE3RI+/4KvAv wqmt5l8nPXMT/PQfSWo5S1qQqW+Oce/nHMrToxV9niygp8S6xNyIlqJVsPklDUEv5rk/ hwFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732714989; x=1733319789; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7njX2qcYZvO6vOSLv4oNfTTNGnncqtHXP/PHkDETIWA=; b=SBJ01GSNNmJEMRNgLzwScqmJ0/gutS89ga3cAU20zAenL984hrm4a/rJvQw95m6lLn Io0LgvVKFuE+Jcu0rZwRC+jdFZmHiDmeununm3PGW1khPi2M0uVrOr9oqXBTBet0ywWZ F860U9RM9Gqjg4/s8d+8c8lOWUaEs+neQcZdwcIt0IepbI3qGykUhHAZml9rRsP8FmyV bnrAf6xCcsdZOWdKPZ93CnDu4lxv+DQeUrvCcb/dUfqiNKzUCiBrRSoMDz38yhpBcVt6 sxzXNzDMk9VixZOVlxndIU6ymMMylyLog/mzOK13+B4Zboh6qpz9yhrSOmzU0TZPi+2g 6HJw== X-Forwarded-Encrypted: i=1; AJvYcCUiTfRZBWAiX4dwkD0+FIRMhedO20wlr5WmMfaKkfC1/MoDfNjXVVvhX/qTK97ywSUxpqcw7sqgIwJRfW0=@vger.kernel.org X-Gm-Message-State: AOJu0YzWtJDz8wUuaqbmpPD+LmeV68gc6CNa2EZPWHfnJrpcbH6Zm6yL ZF41X/fRLVb20/x9pwNJRp2Pd8rIrSMTWJr/56j5DjhPkIf9kH+vrkApIYAXKk0= X-Gm-Gg: ASbGncscPYN3+eY4pj3vxJqMjMVaUSFx0TfS0mr5fNSeCAHmtV848Ox6rY81d/OgLpY tKjqsPIfkG08aYCbwnndOEKixmvsD8kHdVXo0y4sz6e09Qhgu2RwMngBCnOfgxq1bP7afzqxjT+ mcSEblB7LfYrr/KkEQ/cr1kWWtci6qsF6U1J4cFxc2HAPX6QmMauZj6c45v5/JCVuFwp47tg+Hn uPvX4dmVjv3RAjaN6YW2zWHRl23Iq7qbGHyx50cdm6cHD/0YQK0 X-Google-Smtp-Source: AGHT+IHtYk4lGlVanH8Zl/bhihmPXZaX9Uid8tNSLVUiXA+XljSYVslcRPdWrI2XiTM3QzDUET83UQ== X-Received: by 2002:a05:6000:4818:b0:382:5af:e990 with SMTP id ffacd0b85a97d-385c6ee221amr2393086f8f.49.1732714989351; Wed, 27 Nov 2024 05:43:09 -0800 (PST) Received: from linaro.org ([2a00:23c5:6829:901:9ff7:e7c5:5e0f:c5ce]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fad5fa2sm16804645f8f.1.2024.11.27.05.43.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Nov 2024 05:43:08 -0800 (PST) From: Mike Leach To: linux-arm-kernel@lists.infradead.org, coresight@lists.linaro.org, linux-kernel@vger.kernel.org Cc: suzuki.poulose@arm.com, james.clark@arm.com, Mike Leach , Jonathan Corbet , linux-doc@vger.kernel.org Subject: [PATCH v7 9/9] Documentation: coresight: Docs for configuration table load Date: Wed, 27 Nov 2024 13:42:56 +0000 Message-Id: <20241127134256.2254851-10-mike.leach@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20241127134256.2254851-1-mike.leach@linaro.org> References: <20241127134256.2254851-1-mike.leach@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation covering the updates that allow configuration tables to be loaded and unloaded via configfs, along with the demonstration programs in tools/coresight. Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Signed-off-by: Mike Leach Reported-by: Dan Carpenter Reported-by: kernel test robot. --- .../trace/coresight/coresight-config.rst | 287 ++++++++++++++++-- 1 file changed, 264 insertions(+), 23 deletions(-) diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documenta= tion/trace/coresight/coresight-config.rst index 6d5ffa6f7347..235cc6443a86 100644 --- a/Documentation/trace/coresight/coresight-config.rst +++ b/Documentation/trace/coresight/coresight-config.rst @@ -109,20 +109,20 @@ Operation =20 The following steps take place in the operation of a configuration. =20 -1) In this example, the configuration is 'autofdo', which has an - associated feature 'strobing' that works on ETMv4 CoreSight Devices. +1) In this example, the configuration is ``autofdo``, which has an + associated feature ``strobing`` that works on ETMv4 CoreSight Devices. =20 -2) The configuration is enabled. For example 'perf' may select the +2) The configuration is enabled. For example ``perf`` may select the configuration as part of its command line:: =20 perf record -e cs_etm/autofdo/ myapp =20 - which will enable the 'autofdo' configuration. + which will enable the ``autofdo`` configuration. =20 3) perf starts tracing on the system. As each ETMv4 that perf uses for trace is enabled, the configuration manager will check if the ETMv4 has a feature that relates to the currently active configuration. - In this case 'strobing' is enabled & programmed into the ETMv4. + In this case ``strobing`` is enabled & programmed into the ETMv4. =20 4) When the ETMv4 is disabled, any registers marked as needing to be saved will be read back. @@ -136,18 +136,18 @@ Viewing Configurations and Features The set of configurations and features that are currently loaded into the system can be viewed using the configfs API. =20 -Mount configfs as normal and the 'cs-syscfg' subsystem will appear:: +Mount configfs as normal and the ``cs-syscfg`` subsystem will appear:: =20 $ ls /config cs-syscfg stp-policy =20 -This has two sub-directories:: +This has two sub-directories, with the load and unload attribute files:: =20 $ cd cs-syscfg/ $ ls - configurations features + configurations features load unload =20 -The system has the configuration 'autofdo' built in. It may be examined as +The system has the configuration ``autofdo`` built in. It may be examined = as follows:: =20 $ cd configurations/ @@ -162,7 +162,7 @@ follows:: $ cat feature_refs strobing =20 -Each preset declared has a 'preset' subdirectory declared. The values f= or +Each preset declared has a ``preset`` subdirectory declared. The values= for the preset can be examined:: =20 $ cat preset1/values @@ -170,7 +170,7 @@ the preset can be examined:: $ cat preset2/values strobing.window =3D 0x1388 strobing.period =3D 0x4 =20 -The 'enable' and 'preset' files allow the control of a configuration when +The ``enable`` and ``preset`` files allow the control of a configuration w= hen using CoreSight with sysfs. =20 The features referenced by the configuration can be examined in the featur= es @@ -210,18 +210,18 @@ Using Configurations in perf =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D =20 The configurations loaded into the CoreSight configuration management are -also declared in the perf 'cs_etm' event infrastructure so that they can +also declared in the perf ``cs_etm`` event infrastructure so that they can be selected when running trace under perf:: =20 $ ls /sys/devices/cs_etm cpu0 cpu2 events nr_addr_filters power subsystem uevent cpu1 cpu3 format perf_event_mux_interval_ms sinks type =20 -The key directory here is 'events' - a generic perf directory which allows +The key directory here is ``events`` - a generic perf directory which allo= ws selection on the perf command line. As with the sinks entries, this provid= es a hash of the configuration name. =20 -The entry in the 'events' directory uses perfs built in syntax generator +The entry in the ``events`` directory uses perfs built in syntax generator to substitute the syntax for the name when evaluating the command:: =20 $ ls events/ @@ -229,7 +229,7 @@ to substitute the syntax for the name when evaluating t= he command:: $ cat events/autofdo configid=3D0xa7c3dddd =20 -The 'autofdo' configuration may be selected on the perf command line:: +The ``autofdo`` configuration may be selected on the perf command line:: =20 $ perf record -e cs_etm/autofdo/u --per-thread =20 @@ -246,7 +246,7 @@ Using Configurations in sysfs Coresight can be controlled using sysfs. When this is in use then a config= uration can be made active for the devices that are used in the sysfs session. =20 -In a configuration there are 'enable' and 'preset' files. +In a configuration there are ``enable`` and ``preset`` files. =20 To enable a configuration for use with sysfs:: =20 @@ -256,13 +256,13 @@ To enable a configuration for use with sysfs:: This will then use any default parameter values in the features - which ca= n be adjusted as described above. =20 -To use a preset set of parameter values:: +To use a ``preset`` set of parameter values:: =20 $ echo 3 > preset =20 This will select preset3 for the configuration. The valid values for preset are 0 - to deselect presets, and any value of - where a preset sub-directory is present. + where a ``preset`` sub-directory is present. =20 Note that the active sysfs configuration is a global parameter, therefore only a single configuration can be active for sysfs at any one time. @@ -278,9 +278,28 @@ Creating and Loading Custom Configurations =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 Custom configurations and / or features can be dynamically loaded into the -system by using a loadable module. +system by using a loadable module, or by loading a configuration table +through in configfs. =20 -An example of a custom configuration is found in ./samples/coresight. +Loaded configurations can use previously loaded features. The system will +ensure that it is not possible to unload a feature that is currently in +use, by enforcing the unload order as the strict reverse of the load order. + + +Using a Loadable Module +----------------------- + +A new configuration or set of features can be created using the internal +structures used in the drivers, by writing a loadable module that defines +the configuration, and loading this into the kernel at runtime. + +Creating a custom configuration in this way requires the user to compile t= he +module for the specific kernel in use, which limits portability. + +Module Example +~~~~~~~~~~~~~~ + +An example of a custom configuration module is found in ``./samples/coresi= ght``. =20 This creates a new configuration that uses the existing built in strobing feature, but provides a different set of presets. @@ -289,6 +308,228 @@ When the module is loaded, then the configuration app= ears in the configfs file system and is selectable in the same way as the built in configuration described above. =20 -Configurations can use previously loaded features. The system will ensure -that it is not possible to unload a feature that is currently in use, by -enforcing the unload order as the strict reverse of the load order. +The file ``coresight-cfg-sample.c`` contains the configuration and module +initialisation code needed to create the loadable module. + +This will be built alongside the kernel modules if selected in KConfig. +(select ``CONFIG_SAMPLE_CORESIGHT_SYSCFG``). + + +Using a Configuration Table File +-------------------------------- + +Configurations and features can also be dynamically loaded at runtime +using a compact binary table format described below. + +Upon load, this table is validated, expanded into the internal structures +needed for load into the CoreSight subsystem, and loaded into the relevant +CoreSight devices. + +There are additional attributes in the cs-syscfg directory - ``load_table`` +and ``unload_last_table`` that can be used to load and unload configuration +tables. + +As described above, in order to respect configuration dependencies, unload +order is scrictly enforced to be the reverse of load order. + +Load and unload cannot be done if trace is in progress using a configurati= on. + +To load, 'cat' the table file into the load attribute:: + + $ ls /config/cs-syscfg + configurations features load_table show_last_load unload_last_table + $ cat example1.cscfg > /config/cs-syscfg/load_table + $ ls /config/cs-syscfg/configurations/ + autofdo autofdo3 + +``unload_last_table`` can be used to unload the last loaded configuration, +but only if this was loaded as a configuration table. + +To unload, write a non-zero value to ``unload_last_table``. This will unlo= ad +the last loaded table - unless another configuration or feature has been +loaded as a loadable module after the last table load:: + + $ echo 1 > /config/cs-syscfg/unload_last_table + ls /config/cs-syscfg/configurations/ + autofdo + +The type of the last loaded configuration can be determined by reading the +``show_last_load`` attribute:: + + $ cat /config/cs-syscfg/show_last_load + load name: autofdo3 + load type: Runtime Dynamic table load + (configurations: autofdo3 ) + (features: None ) + +This shows the key elements of the loaded configuration - the type of load, +load name, and any configurations and features loaded by the table. + +Unload will fail if the last loaded item was not a dynamic loaded table. +When using ``show_last_load`` a non table load will show:: + + cat /config/cs-syscfg/show_last_load + load name: [Not Set] + load type: Loadable module + + +Generation tools and table examples +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``./tools/coresight`` directory contains example programs to generate = and +read and print binary configuration table files. + +Building the tools creates the ``coresight-cfg-file-gen`` program that will +generate a configuration binary ``example1.cscfg`` that can be loaded into= the +system using configfs. The configuration declared in the source file +``coresight-cfg-example1.c`` is named ``autofdo3`` - the name that will be= used +once loaded. + +The source files ``coresight-cfg-bufw.h`` and ``coresight-cfg-bufw.c`` pro= vide a +standard function to convert a configuration declared in 'C' into the corr= ect +binary buffer format. These files can be re-used to create new custom +configurations. Alternatively, additional examples can be added to the +``coresight-cfg-file-gen`` program:: + + $ ./coresight-cfg-file-gen + Coresight Configuration file Generator + + Generating example1 example + Generating example2 example + +The program ``coresight-cfg-file-read`` can read back and print a configur= ation +binary. This is built using the file reader from the driver code +(``coresight-config-file.c``), which is copied over into ``./tools/coresig= ht`` at +build time.:: + + ./coresight-cfg-file-read example1.cscfg + CoreSight Configuration file reader + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + + Configuration 1 + Name:- autofdo3 + Description:- + Setup ETMs with strobing for autofdo + Supplied presets allow experimentation with mark-space ratio for vario= us loads + + Uses 1 features:- + Feature-1: strobing + + Provides 4 sets of preset values, 2 presets per set + set[0]: 0x7d0, 0x64, + set[1]: 0x7d0, 0x3e8, + set[2]: 0x7d0, 0x1388, + set[3]: 0x7d0, 0x2710, + + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + File contains no features + + +CoreSight Configuration Table Format +------------------------------------ + +The file format is defined in the source file ``coresight-config-table.h`` + +The source reader and generator examples use/produce a table in this forma= t, +as a binary file. + +This arrangement is reproduced below:- + +Overall Table structure +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_table_header] // Mandatory + [CONFIG_ELEM]* // Optional - multiple, defined by cscfg_table_he= ader.nr_configs + [FEATURE_ELEM]* // Optional - multiple, defined by cscfg_table_he= ader.nr_features + +Table is invalid if both [CONFIG_ELEM] and [FEATURE_ELEM] are omitted. + +A table that contains only [FEATURE_ELEM] may be loaded, and the features = used +by subsequently loaded files with [CONFIG_ELEM] elements. + +Element Name Strings +~~~~~~~~~~~~~~~~~~~~ + +Configuration name strings are required to consist of alphanumeric charact= ers and '_' only. Other special characters are not permitted. + +For example ``my_config_2`` is a valid name, while ``this-bad-config#5`` w= ill not work. + +This is in order to comply with the requirements of the perf command line. + +It is recommended that Feature and Parameter names use the same convention= to allow for future enhancements to the command line syntax. + +CONFIG_ELEM element +~~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_table_elem_header] // header length value to end o= f feature strings. + [cscfg_table_elem_str] // name of the configuration. + // (see element string name req= uirements) + [cscfg_table_elem_str] // description of configuration. + [u16 value](nr_presets) // number of defined sets prese= ts values. + [u32 value](nr_total_params) // total parameters defined by = all used features. + [u16 value](nr_feat_refs) // number of features reference= d by the configuration + [u64 values] * (nr_presets * nr_total_params) // the preset values. + [cscfg_table_elem_str] * (nr_feat_refs) // names of features used in th= e configurations. + +FEATURE_ELEM element +~~~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_table_elem_header] // header length is total bytes= to end of param structures. + [cscfg_table_elem_str] // feature name. + [cscfg_table_elem_str] // feature description. + [u32 value](match_flags) // flags to associate the featu= re with a device. + [u16 value](nr_regs) // number of registers. + [u16 value](nr_params) // number of parameters. + [cscfg_regval_desc struct] * (nr_regs) // register definitions + [PARAM_ELEM] * (nr_params) // parameters definitions + +PARAM_ELEM element +~~~~~~~~~~~~~~~~~~ + +:: + + [cscfg_table_elem_str] // parameter name. + [u64 value](param_value) // initial value. + +Additional definitions +~~~~~~~~~~~~~~~~~~~~~~ + +The following structures are defined in ``coresight-config-file.h`` + + * ``struct cscfg_table_header`` : This structure contains an initial magi= c number, the total + length of the table, and the number of configurations and features in t= he table. + * ``struct cscfg_table_elem_header``: This defines the total length and t= ype of a CONFIG_ELEM + or a FEATURE_ELEM. + * ``struct cscfg_table_elem_str``: This defines a string and its length. + +The magic number in cscfg_table_header is defined as two bitfields:: + + [31:8] Fixed magic number to identify table type. + [7:0] Current table format version. + +The following defines determine the maximum overall table size and maximum= individual +string size + + * ``CSCFG_TABLE_MAXSIZE`` : maximum overall table size. + * ``CSCFG_TABLE_STR_MAXSIZE`` : maximum individual string size. + +Load Dependencies +~~~~~~~~~~~~~~~~~ + +Files may be unloaded only in the strict reverse order of loading. This is= enforced by the +configuration system. + +This is to ensure that any load dependencies are maintained. + +A configuration table that contains a CONFIG_ELEM that references named fe= atures "feat_A" and "feat_B" will load only if either:- + +a) "feat_A" and/or "feat_B" has been loaded previously, or are present as = built-in / module loaded features. +b) "feat_A" and/or "feat_B" are declared as FEAT_ELEM in the same table as= the CONFIG_ELEM. + +Tables that contain features or configurations with the same names as thos= e already loaded will fail to load. --=20 2.25.1