Update coresight-config.h and the coresight-config-file.c & .h
to allow use in userspace programs.
Use __KERNEL__ defines to filter out driver only structures and
elements so that user space programs can use the descriptor structures.
Abstract memory allocation in coresight-config-file.c to allow read
file functions to be run in userspace and kernel drivers.
Signed-off-by: Mike Leach <mike.leach@linaro.org>
---
.../coresight/coresight-config-file.c | 117 +++++++++++++-----
.../hwtracing/coresight/coresight-config.h | 12 ++
2 files changed, 101 insertions(+), 28 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c
index be11261e3a14..cf9f178eef97 100644
--- a/drivers/hwtracing/coresight/coresight-config-file.c
+++ b/drivers/hwtracing/coresight/coresight-config-file.c
@@ -7,6 +7,63 @@
#include "coresight-config.h"
#include "coresight-config-file.h"
+/*
+ * To allow reuse of this source in tools, define memory allocation fns according
+ * to build environment.
+ */
+
+#ifdef __KERNEL__
+
+static void *cscfg_calloc(size_t num, size_t size)
+{
+ return kcalloc(num, size, GFP_KERNEL);
+}
+
+static char *cscfg_strdup(const char *str)
+{
+ return kstrdup(str, GFP_KERNEL);
+}
+
+static void *cscfg_zalloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+static void cscfg_free(void *mem)
+{
+ kfree(mem);
+}
+#else
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void *cscfg_calloc(size_t num, size_t size)
+{
+ return calloc(num, size);
+}
+
+static char *cscfg_strdup(const char *str)
+{
+ return strdup(str);
+}
+
+static void *cscfg_zalloc(size_t size)
+{
+ void *ptr = malloc(size);
+
+ if (ptr)
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+static void cscfg_free(void *mem)
+{
+ free(mem);
+}
+#endif
+
#define cscfg_extract_u64(val64) { \
val64 = *(u64 *)(buffer + used); \
used += sizeof(u64); \
@@ -80,6 +137,7 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf
struct cscfg_file_elem_str *elem_str)
{
int used = *buf_used;
+ const u8 *str;
if ((buflen - used) < sizeof(u16))
return -EINVAL;
@@ -89,11 +147,13 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf
if ((buflen - used) < elem_str->str_len)
return -EINVAL;
+ str = buffer + used;
+
/* check for 0 termination */
- if (buffer[used + (elem_str->str_len - 1)] != 0)
+ if (str[elem_str->str_len - 1] != 0)
return -EINVAL;
- elem_str->str = kstrdup((char *)(buffer + used), GFP_KERNEL);
+ elem_str->str = cscfg_strdup((char *)str);
used += elem_str->str_len;
*buf_used = used;
@@ -104,12 +164,13 @@ static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays,
int nr_features, int nr_configs)
{
/* arrays are 0 terminated - nr_configs & nr_features elements */
- desc_arrays->config_descs = kcalloc(nr_configs + 1, sizeof(struct cscfg_config_desc *),
- GFP_KERNEL);
+ desc_arrays->config_descs = cscfg_calloc(nr_configs + 1,
+ sizeof(struct cscfg_config_desc *));
if (!desc_arrays->config_descs)
return -ENOMEM;
- desc_arrays->feat_descs = kcalloc(nr_features + 1, sizeof(struct cscfg_feature_desc *),
- GFP_KERNEL);
+
+ desc_arrays->feat_descs = cscfg_calloc(nr_features + 1,
+ sizeof(struct cscfg_feature_desc *));
if (!desc_arrays->feat_descs)
return -ENOMEM;
return 0;
@@ -124,24 +185,24 @@ static void cscfg_file_free_config_desc(struct cscfg_config_desc *config_desc)
return;
/* free presets */
- kfree(config_desc->presets);
+ cscfg_free((void *)config_desc->presets);
/* free feat ref strings */
if (config_desc->nr_feat_refs) {
/* each string */
for (i = 0; i < config_desc->nr_feat_refs; i++)
- kfree(config_desc->feat_ref_names[i]);
+ cscfg_free((void *)config_desc->feat_ref_names[i]);
/* and the char * array */
- kfree(config_desc->feat_ref_names);
+ cscfg_free((void *)config_desc->feat_ref_names);
}
/* next the strings */
- kfree(config_desc->name);
- kfree(config_desc->description);
+ cscfg_free((void *)config_desc->name);
+ cscfg_free((void *)config_desc->description);
/* finally the struct itself */
- kfree(config_desc);
+ cscfg_free((void *)config_desc);
}
static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *buf_used,
@@ -166,7 +227,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
return 0;
/* we have a config - allocate the descriptor */
- config_desc = kzalloc(sizeof(struct cscfg_config_desc), GFP_KERNEL);
+ config_desc = cscfg_zalloc(sizeof(struct cscfg_config_desc));
if (!config_desc)
return -ENOMEM;
@@ -192,7 +253,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
/* read the array of 64bit presets if present */
nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets;
if (nr_preset_vals) {
- presets = kcalloc(nr_preset_vals, sizeof(u64), GFP_KERNEL);
+ presets = cscfg_calloc(nr_preset_vals, sizeof(u64));
if (!presets)
return -ENOMEM;
@@ -207,8 +268,8 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
/* read the array of feature names referenced by the config */
if (config_desc->nr_feat_refs) {
- config_desc->feat_ref_names = kcalloc(config_desc->nr_feat_refs,
- sizeof(char *), GFP_KERNEL);
+ config_desc->feat_ref_names = cscfg_calloc(config_desc->nr_feat_refs,
+ sizeof(char *));
if (!config_desc->feat_ref_names)
return -ENOMEM;
@@ -289,17 +350,17 @@ static void cscfg_file_free_feat_desc(struct cscfg_feature_desc *feat_desc)
return;
/* free up the register descriptor array */
- kfree(feat_desc->regs_desc);
+ cscfg_free((void *)feat_desc->regs_desc);
/* free up the parameters array */
- kfree(feat_desc->params_desc);
+ cscfg_free((void *)feat_desc->params_desc);
/* name and description strings */
- kfree(feat_desc->name);
- kfree(feat_desc->description);
+ cscfg_free((void *)feat_desc->name);
+ cscfg_free((void *)feat_desc->description);
/* finally the struct itself */
- kfree(feat_desc);
+ cscfg_free((void *)feat_desc);
}
static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int *buf_used,
@@ -314,7 +375,7 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
u32 val32;
/* allocate the feature descriptor object */
- feat_desc = kzalloc(sizeof(struct cscfg_feature_desc), GFP_KERNEL);
+ feat_desc = cscfg_zalloc(sizeof(struct cscfg_feature_desc));
if (!feat_desc)
return -ENOMEM;
@@ -353,8 +414,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs);
if ((buflen - used) < nr_regs_bytes)
return -EINVAL;
- feat_desc->regs_desc = kcalloc(feat_desc->nr_regs,
- sizeof(struct cscfg_regval_desc), GFP_KERNEL);
+ feat_desc->regs_desc = cscfg_calloc(feat_desc->nr_regs,
+ sizeof(struct cscfg_regval_desc));
if (!feat_desc->regs_desc)
return -ENOMEM;
@@ -368,8 +429,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
/* parameter descriptors - string + 64 bit value */
if (feat_desc->nr_params) {
- feat_desc->params_desc = kcalloc(feat_desc->nr_params,
- sizeof(struct cscfg_parameter_desc), GFP_KERNEL);
+ feat_desc->params_desc = cscfg_calloc(feat_desc->nr_params,
+ sizeof(struct cscfg_parameter_desc));
if (!feat_desc->params_desc)
return -ENOMEM;
for (i = 0; i < feat_desc->nr_params; i++) {
@@ -515,6 +576,6 @@ void cscfg_file_free_load_descs(struct cscfg_fs_load_descs *desc_arrays)
}
/* finally free up the load descs pointer arrays */
- kfree(desc_arrays->config_descs);
- kfree(desc_arrays->feat_descs);
+ cscfg_free(desc_arrays->config_descs);
+ cscfg_free(desc_arrays->feat_descs);
}
diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
index ad212954f99e..58d4f179ff0d 100644
--- a/drivers/hwtracing/coresight/coresight-config.h
+++ b/drivers/hwtracing/coresight/coresight-config.h
@@ -7,7 +7,14 @@
#ifndef _CORESIGHT_CORESIGHT_CONFIG_H
#define _CORESIGHT_CORESIGHT_CONFIG_H
+/*
+ * Filter out kernel only portions of the file to allow user space programs
+ * to use the descriptor definitions.
+ */
+#ifdef __KERNEL__
#include <linux/coresight.h>
+#endif
+
#include <linux/types.h>
/* CoreSight Configuration Management - component and system wide configuration */
@@ -100,6 +107,10 @@ struct cscfg_fs_load_descs {
struct cscfg_feature_desc **feat_descs;
};
+
+/* remainder of header is used by the kernel drivers only */
+#ifdef __KERNEL__
+
/**
* Device feature descriptor - combination of registers and parameters to
* program a device to implement a specific complex function.
@@ -274,4 +285,5 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
/* reset a feature to default values */
void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);
+#endif /* __KERNEL__ */
#endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
--
2.17.1
On Mon, Dec 19, 2022 at 11:46:36PM +0000, Mike Leach wrote: > Update coresight-config.h and the coresight-config-file.c & .h > to allow use in userspace programs. > > Use __KERNEL__ defines to filter out driver only structures and > elements so that user space programs can use the descriptor structures. > > Abstract memory allocation in coresight-config-file.c to allow read > file functions to be run in userspace and kernel drivers. That's now how kernel code is written.
I'll rework this in the next set. Thanks for the review Mike On Tue, 27 Dec 2022 at 17:10, Christoph Hellwig <hch@infradead.org> wrote: > > On Mon, Dec 19, 2022 at 11:46:36PM +0000, Mike Leach wrote: > > Update coresight-config.h and the coresight-config-file.c & .h > > to allow use in userspace programs. > > > > Use __KERNEL__ defines to filter out driver only structures and > > elements so that user space programs can use the descriptor structures. > > > > Abstract memory allocation in coresight-config-file.c to allow read > > file functions to be run in userspace and kernel drivers. > > That's now how kernel code is written. -- Mike Leach Principal Engineer, ARM Ltd. Manchester Design Centre. UK
© 2016 - 2025 Red Hat, Inc.