bootconfig: Allocate xbc_data inside xbc_init()

Allocate 'xbc_data' in the xbc_init() so that it does
not need to care about the ownership of the copied
data.

Link: https://lkml.kernel.org/r/163177339986.682366.898762699429769117.stgit@devnote2

Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
Masami Hiramatsu
2021-09-16 15:23:20 +09:00
committed by Steven Rostedt (VMware)
parent 6644c654ea
commit bdac5c2b24
4 changed files with 27 additions and 27 deletions

View File

@@ -789,6 +789,7 @@ static int __init xbc_verify_tree(void)
*/
void __init xbc_destroy_all(void)
{
memblock_free_ptr(xbc_data, xbc_data_size);
xbc_data = NULL;
xbc_data_size = 0;
xbc_node_num = 0;
@@ -799,19 +800,20 @@ void __init xbc_destroy_all(void)
/**
* xbc_init() - Parse given XBC file and build XBC internal tree
* @buf: boot config text
* @data: The boot config text original data
* @size: The size of @data
* @emsg: A pointer of const char * to store the error message
* @epos: A pointer of int to store the error position
*
* This parses the boot config text in @buf. @buf must be a
* null terminated string and smaller than XBC_DATA_MAX.
* This parses the boot config text in @data. @size must be smaller
* than XBC_DATA_MAX.
* Return the number of stored nodes (>0) if succeeded, or -errno
* if there is any error.
* In error cases, @emsg will be updated with an error message and
* @epos will be updated with the error position which is the byte offset
* of @buf. If the error is not a parser error, @epos will be -1.
*/
int __init xbc_init(char *buf, const char **emsg, int *epos)
int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos)
{
char *p, *q;
int ret, c;
@@ -824,28 +826,35 @@ int __init xbc_init(char *buf, const char **emsg, int *epos)
*emsg = "Bootconfig is already initialized";
return -EBUSY;
}
ret = strlen(buf);
if (ret > XBC_DATA_MAX - 1 || ret == 0) {
if (size > XBC_DATA_MAX || size == 0) {
if (emsg)
*emsg = ret ? "Config data is too big" :
*emsg = size ? "Config data is too big" :
"Config data is empty";
return -ERANGE;
}
xbc_data = memblock_alloc(size + 1, SMP_CACHE_BYTES);
if (!xbc_data) {
if (emsg)
*emsg = "Failed to allocate bootconfig data";
return -ENOMEM;
}
memcpy(xbc_data, data, size);
xbc_data[size] = '\0';
xbc_data_size = size + 1;
xbc_nodes = memblock_alloc(sizeof(struct xbc_node) * XBC_NODE_MAX,
SMP_CACHE_BYTES);
if (!xbc_nodes) {
if (emsg)
*emsg = "Failed to allocate bootconfig nodes";
xbc_destroy_all();
return -ENOMEM;
}
memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX);
xbc_data = buf;
xbc_data_size = ret + 1;
last_parent = NULL;
p = buf;
last_parent = NULL;
p = xbc_data;
do {
q = strpbrk(p, "{}=+;:\n#");
if (!q) {